функция друга базового класса и производного класса

У меня есть базовый класс Fraction и производный класс iFraction. Дробь представляет собой неправильные дроби, а iFraction представляет смешанные фракции.

class Fraction {...};
class iFraction : public Fraction {...};

Теперь я хочу объявить функцию друга этих двух классов, а именно convertF. Функция convertF может преобразовывать неправильные дроби (Fraction) в смешанные дроби (iFraction). Как холодно я это делаю? Собственно, я бы хотел объявить функцию вот так:

friend iFraction convertF (Fraction &Fra);

Однако он не может быть объявлен в базовой фракции calss. Зачем?


person user1305904    schedule 19.04.2012    source источник


Ответы (3)


Для этого вам не нужна функция друга. Есть два способа сделать это: использовать dynamic_cast или написать конструктор преобразования, который принимает объект Fraction и преобразует его в объект iFraction. Я не уверен, что второй вариант вообще хороший вариант, но попробовать.

person DumbCoder    schedule 19.04.2012
comment
Спасибо за Ваш ответ. Однако сейчас я не знаю, что такое dynamic_cast. Я просто новичок. - person user1305904; 19.04.2012

Поскольку отношения friend не наследуются, вам необходимо объявить convertF другом обоих классов. Но вам это нужно только в том случае, если функции требуется доступ к внутренним компонентам этих классов - уверены ли вы, что открытого интерфейса классов недостаточно?

Еще одна причина избегать такого двойного друга состоит в том, что он создает круговую зависимость между этими классами через сигнатуру convertF.

Обновление: именно поэтому вы не можете объявить свою функцию друга так, как показано выше. Чтобы это работало, компилятору необходимо знать полное определение iFraction, пока он еще не закончил определение базового класса Fraction, что невозможно.

Технически это могло бы работать и наоборот, путем прямого объявления iFraction. Хотя все равно не считаю это хорошим решением. Вы уверены, что ваша иерархия классов верна?

person Péter Török    schedule 19.04.2012
comment
Спасибо за Ваш ответ. Теперь я понимаю, почему я не могу этого сделать. Но как я мог реализовать свою цель - преобразовать Fraction в iFraction? - person user1305904; 19.04.2012
comment
класс Fraction имеет два элемента данных: один для числителя и один для знаменателя. У класса iFraction есть еще один член данных iNum, который представляет собой часть целого числа. - person user1305904; 19.04.2012
comment
@ user1305904, после двойной проверки условий теперь я уверен, что у вас неправильные отношения наследования: смешанная дробь не неправильная дробь. Конечно, преобразование между ними совершенно разумно. - person Péter Török; 19.04.2012
comment
вы можете быть правы. Этот код предназначен только для отработки моих навыков программирования. в любом случае спасибо за ваше мнение. - person user1305904; 19.04.2012

Прочтите это: http://www.cprogramming.com/tutorial/friends.html

Всегда старайтесь сначала понять концепцию.

person Ockham    schedule 19.04.2012