Как бы вы указали «this» базового класса из метода вложенного класса? - PullRequest
1 голос
/ 06 февраля 2020

У меня есть класс, вложенный в базовый класс, например:

class Base {
public:
    void methodB() { std::cout << "method B"; }
    class Nested {
    public:
        void methodA() { methodB(); }
    };
    Nested * member;
};

Это, очевидно, приводит к ошибке компилятора:

Cannot call member function methodB without object

, потому что methodB не объявлен как stati c. Это будет нормально в main, потому что methodB будет вызываться при выполнении instanceOfBase.member->methodA(), что, в свою очередь, вызовет methodB, но проблема, с которой я сталкиваюсь, заключается в том, что я не знаю, как получить доступ к базовому указателю this на instanceOfBase от объекта-члена.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Объект вложенного класса не связан напрямую с объектом класса, в который вложено его определение. Рассмотрим что-то вроде этого:

Base::Nested{}.methodA()

Какой объект Base будет работать?

Если у вас есть некоторый инвариант, согласно которому объекты Nested всегда содержатся в Base объектах, то вам необходимо поддерживать эту ссылку. Например, вы можете передать указатель this объекта Base на конструктор объекта Nested в конструкторе Base:

class Base {
public:
    class Nested {
    public:
        Nested(Base* owner) : owner{owner} {}
        void methodA() { owner->methodB(); }
        Base* owner;
    };

    Base() : member{this} {}
    void methodB() { std::cout << "method B"; }

    Nested member;
};

Live Demo

2 голосов
/ 06 февраля 2020

базовый класс ...

«Базовый» класс означает нечто иное. Вы спрашиваете о external классе.

methodB будет вызываться при выполнении instanceOfBase.member-> methodA (), который, в свою очередь, вызовет methodB, но проблема I Я сталкиваюсь с тем, что я не знаю, как получить доступ к лежащему в основе этому указателю на instanceOfBase из его объекта-члена.

Нет "лежащего в основе" этого указателя на instanceOfBase. Структура выглядит следующим образом:

Base ---> Nested
      ^
      |
      pointer

«База» не содержит вложенных объектов, но указывает на один. Вложенные не содержат никаких «базовых» объектов и не указывают на них. Поскольку он не связан с какой-либо «Базой», нет способа получить доступ к такому «Базовому» объекту из «Вложенного».

Одним из решений является предоставление функции-оболочки в «Базе», которая передает экземпляр в остроконечный вложенный объект:

class Base {
public:
    // ...
    void methodA() {
        member->methodA(*this);
    }
};
// usage
instanceOfBase.methodA();
...