Как я могу инициализировать элемент указателя, чтобы он указывал на его инкапсулирующий экземпляр?

0

Предположим, у меня было следующее:

class A; // forward declaration

class A {
public:
    A(A* parent) : parent(parent) {}
    A* parent;
    virtual void foo() = 0;
};

class B : public A {
public:
    B() : A(this) {}
    void foo() {}
};

При создании экземпляров двух отдельных экземпляров класса B parent указатели одинаковы в каждом из экземпляров. Любая идея почему?

EDIT: Я считаю, что вышеизложенное теперь более точно моделирует то, что у меня есть в моем коде.

  • 0
    this должно работать просто отлично. Можете ли вы опубликовать фактическое сообщение об ошибке?
  • 0
    Значение this (адрес объекта) прекрасно подходит для использования в этой точке, независимо от того, инициализировано ли содержимое объекта или нет.
Показать ещё 15 комментариев
Теги:
pointers
initialization
forward-declaration
this

2 ответа

1
Лучший ответ

Вам нужно написать конструктор копии. Конструктор по умолчанию не вызывается при копировании экземпляра, а создатель, созданный компилятором, скопирует parent указатель из исходного экземпляра.

A(A const &other) : parent(this) {}

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

Также подумайте о том, что должно произойти при копировании или назначении из экземпляра, чей parent был изменен с его по умолчанию. В таком случае, если копия/правопреемник получит тот же самый родитель, что и оригинал? Если это так, то ваш конструктор копирования и оператор присваивания должны будут проверить, является ли parent == this и ведет себя по-разному в зависимости от результата. Может быть проще просто использовать значение nullptr в качестве значения по умолчанию - в любом случае вам нужна специальная обработка для экземпляров без родителей, но нулевой указатель, по крайней мере, делает очевидным, что ни один "реальный" родитель еще не назначен.

  • 0
    Просто, чтобы избежать сообщений компилятора, я бы пропустил 'other'.
  • 0
    Нужен ли мне конструктор копирования для A и B ? Или просто A ?
Показать ещё 3 комментария
0

Добавьте точку с запятой после определения класса. Это отсутствует в примере, который вы указали. Компиляторы иногда дают для этого загадочные сообщения об ошибках.

  • 0
    Нет, это не так, приведенный выше пример кода - это упрощенная версия, которую я быстро набрал вручную - отсутствие трейлинга ; была ошибкой с моей стороны, но не является источником моей проблемы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню