Как получить доступ к данным материнского класса из детского класса? - PullRequest
0 голосов
/ 19 октября 2018

Как я могу получить доступ к данным материнского класса из дочернего класса, не создавая instace?У меня что-то вроде:

#include <iostream>
class mother {
    private:

    public:
        mother(){}
        virtual ~mother(){}
        virtual void func() const {std::cout << "mother " << dat <<std::endl;}
        virtual void dat_set(std::string arg){dat=arg;}
        std::string dat;
};

class child:mother {
    public:
        child(){}
        ~child(){}
        void dat_set(std::string const arg) override { mother::dat_set(arg); }
        void func() const override { std::cout << "child " << mother::dat << std::endl; }
};

int main (void) {
    auto tmp = new mother();
    tmp->dat_set("test");
    auto foo = new child();
    foo->func();
}

Как мне убедиться, что func(), вызванный foo, получает доступ к данным, хранящимся в mother?

РЕДАКТИРОВАТЬ Разве я не смогу сделать std::string dat a static std::string dat?Я пытался это, но я получаю ошибки компилятора в соответствии с

/tmp/ccZV7Y4n.o: In function `child::func()':
main.cpp:(.text._ZN5child4funcEv[_ZN5child4funcEv]+0x1d): undefined reference to `mother::dat[abi:cxx11]'

1 Ответ

0 голосов
/ 19 октября 2018

Хитрость в получении доступа к функциям внутри базовых классов из производных классов состоит в том, чтобы повторно объявить их с помощью virtual и override спецификаторов ...

Сначала создайте деструктор virtual ... ( Поскольку ваш компилятор не хочет, чтобы виртуальные функции внутри класса без виртуального деструктора )

virtual ~mother() = default; // If the compiler is happy, we all are happy...

А затем сделайте ваши функции виртуальными ...

virtual void dat_set(std::string const arg) { dat = arg; }
virtual void func() const { std::cout << "mother " << dat << std::endl; }

Вы должны определить его снова внутри дочернего класса, так как ребенок не может стать мать, и именно поэтому вы не можете получить доступ к этим функциям ...

void dat_set(std::string const arg) override { mother::dat_set(arg); }
void func() const override { mother::func(); }

Здесь вы должны иметь точно такое же объявление, которое вы имели вбазовый класс (кроме virtual , который является избыточным при использовании override ...) и добавляет спецификатор override, которыйобъявляет ту же функцию, что и в базовом классе внутри дочернего класса ...

Для поведения просто поставьте mother::func() (mother::dat_set(/*params go here*/) для вызова функции с параметрами, и, держу пари, вы уже знаете, что ) для вызова соответствующей функции ...

Примечание: Спецификатор переопределения (так как C ++ 11 ) похож на виртуальный спецификатор, за исключением того, что он может использоваться только в классах / структурах с производными данными и делает использование виртуальных внутри дочерних объявлений необязательным (в базовом классе)вместо этого вы должны использовать виртуальный) ...


Редактировать: Вы можете назначить производный класс базовому классу, но невозможно сделать наоборот,и это причина, по которой ваш код не работает ... Близкой попыткой сделать что-то подобное было бы использование пространств имен, например:

namespace some_namespace
{
    static std::string dat;
    // The child and mother class declarations and other things go here...
}

С уважением,

Ruks.

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