Почему операторы << и >> вызываются в базовом классе, если они определены как «друг» при вызове << и >> в дочернем классе?
Код:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
class Baza
{
protected:
int n;
public:
Baza() { cout << "B\n"; }
virtual ~Baza() { cout << "~B\n"; }
friend istream& operator>>(istream& in, Baza& b);
friend ostream& operator<<(ostream& out, const Baza& b);
};
istream& operator>>(istream& in, Baza& b)
{
cout<<"op >>"<<endl;
return in;
}
ostream& operator<<(ostream& out, const Baza& b)
{
cout<<"op<<"<<endl;
return out;
}
class Derivata : public Baza
{
public:
Derivata() { cout << "D\n"; }
~Derivata() { cout << "~D\n"; }
};
int main()
{
vector<Derivata> v;
v.push_back(new Derivata);
// works
Derivata d;
cin>>d;
cout<<d;
return 0;
}
Создает ли компилятор С++ операторы, которые по умолчанию вызывают оператор метода базового класса при компиляции?
Перефразирую: в базовом классе (который является базой) определены операторы << и >> как дружественные. Класс Derivata наследует «базу» (базовый класс), но операторы не наследуются, поскольку они являются друзьями. почему они вызываются, если я использую >> и << в классе «derivata»?
К другу это не имеет никакого отношения. Derivata — это Baza, и операторы с Baza& выбраны удачно.
извините, я изменил.
Более простой пример, демонстрирующий то же явление: void foo(const Baza&) {} int main() { Derivata d; foo(d); } Ожидаете ли вы, что эта версия не сработает?
операторы >> и << определяются как дружественные методы, поэтому они не наследуются.
ох блин. в базовом классе (который является базой) определены операторы << и >> как Friend. Класс Derivata наследует «базу» (базовый класс), но операторы не наследуются, поскольку они являются друзьями. почему они вызываются, если я использую >> и << в классе «derivata»?
Вы можете удалить friend ... и убедиться, что friend не является темой вашего вопроса.
@273k это шутка?
@sticknycu Ничего не наследуется. Это просто нормальное разрешение перегрузки. friend функции не являются частью класса, даже если они определены в определении класса. Это обычные автономные функции.
Я не шучу. Вы чрезмерно сосредоточены на friend.
Ну, вопрос в том, как они тогда называются, если они не определены в классе «Derivata», и почему называются операторами базового класса?
Как они называются, показано в четвёртом комментарии. Они НЕ являются операторами базового класса.
Компилятор создает конструктор «derivata», который вызывает «базовый» класс (по сути, экземпляр «базового» класса и вызывающий методы << и >> ?





Определенные вами operator>> и operator<< никоим образом не являются частью класса Baza. Ключевое слово friend этого не делает; он просто дает им разрешение на доступ к участникам Bazaprivate и protected.
Таким образом, то, что у вас есть, ничем не отличается от этого:
class Baza {};
class Derivata : public Baza {};
void some_function(Baza&) {}
int main() {
Derivata d;
some_function(d);
}
Ссылка на базовый класс может быть привязана к объекту класса, производного от этого базового класса, поэтому Baza& может быть привязан к объекту Derivata. Это позволяет передавать объекты производного класса функциям, которые принимают ссылки на базовый класс.
Замена some_function перегруженным оператором ничего не меняет в семантике того, как он ищется или какие объекты ему можно передавать. Все, что он меняет, — это синтаксис, используемый для его вызова.
Э-э, производный класс наследует вещи базового класса, например, операторы. Это ожидаемое поведение.