Оператор друга << и >> в базовом классе без дочернего класса, но все равно вызывается

Почему операторы << и >> вызываются в базовом классе, если они определены как «друг» при вызове << и >> в дочернем классе?

Код:

#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»?

Э-э, производный класс наследует вещи базового класса, например, операторы. Это ожидаемое поведение.

Dúthomhas 19.05.2024 23:13

К другу это не имеет никакого отношения. Derivata — это Baza, и операторы с Baza& выбраны удачно.

3CxEZiVlQ 19.05.2024 23:16

извините, я изменил.

sticknycu 19.05.2024 23:17

Более простой пример, демонстрирующий то же явление: void foo(const Baza&) {} int main() { Derivata d; foo(d); } Ожидаете ли вы, что эта версия не сработает?

JaMiT 19.05.2024 23:17

операторы >> и << определяются как дружественные методы, поэтому они не наследуются.

sticknycu 19.05.2024 23:18

ох блин. в базовом классе (который является базой) определены операторы << и >> как Friend. Класс Derivata наследует «базу» (базовый класс), но операторы не наследуются, поскольку они являются друзьями. почему они вызываются, если я использую >> и << в классе «derivata»?

sticknycu 19.05.2024 23:21

Вы можете удалить friend ... и убедиться, что friend не является темой вашего вопроса.

3CxEZiVlQ 19.05.2024 23:21

@273k это шутка?

sticknycu 19.05.2024 23:22

@sticknycu Ничего не наследуется. Это просто нормальное разрешение перегрузки. friend функции не являются частью класса, даже если они определены в определении класса. Это обычные автономные функции.

Miles Budnek 19.05.2024 23:22

Я не шучу. Вы чрезмерно сосредоточены на friend.

3CxEZiVlQ 19.05.2024 23:24

Ну, вопрос в том, как они тогда называются, если они не определены в классе «Derivata», и почему называются операторами базового класса?

sticknycu 19.05.2024 23:24

Как они называются, показано в четвёртом комментарии. Они НЕ являются операторами базового класса.

3CxEZiVlQ 19.05.2024 23:25

Компилятор создает конструктор «derivata», который вызывает «базовый» класс (по сути, экземпляр «базового» класса и вызывающий методы << и >> ?

sticknycu 19.05.2024 23:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
13
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Определенные вами 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 перегруженным оператором ничего не меняет в семантике того, как он ищется или какие объекты ему можно передавать. Все, что он меняет, — это синтаксис, используемый для его вызова.

Другие вопросы по теме