Как работает наследование атрибутов в C ++? - PullRequest
2 голосов
/ 20 апреля 2020

Предположим, вы хотите воспроизвести следующий Python фрагмент:

class Base:
    name = "base"

    def announce(self):
        print(self.name)

class Derived(Base):
    name = "derived"

Base().announce()
Derived().announce()

..., который выдает:

"base"
"derived"

Изначально вы можете быть склонны написать что-то вроде следующее:

#include <iostream>
#include <string>

struct Base {
    std::string name = "base";
    void announce() {
        std::cout << name << std::endl;
    }
};

struct Derived : public Base {
    std::string name = "movie";
};

int main() {
    Base().announce();
    Derived().announce();
    return 0;
}

Но здесь Derived.name просто тени Base.name. Вызов Derived.announce() ссылается на Base.name и печатает "base".

Есть ли способ реализовать это поведение? Идеально без шаблонов классов, если это возможно.

1 Ответ

3 голосов
/ 20 апреля 2020

C ++ не работает как Python (что неудивительно, ведь это два очень разных языка), а переменные-члены, определенные в унаследованном классе, действительно определяют новую переменную, которая не связана с переменными родительский класс.

Одним из возможных решений является создание второго (возможно защищенного) конструктора Base, который принимает name в качестве аргумента, а затем класс Derived может использовать его для инициализации члена:

struct Base {
    Base() = default;  // A defaulted default constructor

    std::string name = "base";
    void announce() {
        std::cout << name << std::endl;
    }

protected:
    explicit Base(std::string name)
        : name{ std::move(name) }  // Initialize the member
    {
    }
};

struct Derived : public Base {
    Derived()
        : Base("movie")  // Initialize the base class using the special constructor
    {
    }
};

Требуется конструктор по умолчанию Base, так как если вы объявите другой конструктор, компилятор не будет автоматически генерировать конструктор по умолчанию для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...