Безопасно ли передавать указатели на элементы данных в конструктор базового класса?

Безопасно ли передавать указатели на элементы данных в конструктор базового класса? т.е. является ли макет памяти элементов данных производного класса, по крайней мере, уже установленным до того, как вызывается конструктор базового класса, даже если элементы данных еще не инициализированы?

Очевидно, разыменование указателей должно быть сделано только после завершения строительства, и объекты, на которые указывает, уже действуют. Но вопрос в том, гарантирует ли он, что указатели, полученные конструктором базового класса, на самом деле все еще указывают на свои объекты после завершения построения производного объекта.

Мотивация обеспечивает некоторую функциональность базового класса, например, итерацию над указателями на объекты, предоставляемые при построении, и что-то делать для каждого в более позднее время.

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

Пример:

#include <iostream>
#include <utility>
#include <vector>

struct Base {
   Base(std::initializer_list<int*> ptrs = {}) : ptrs_(ptrs) {}
   std::vector<int*> ptrs_;
};

struct Derived : public Base {
    Derived() : Base{{&a_,&b_,&c_}} {}
    int a_=1, b_=2, c_=3;
};

int main()
{
    Derived obj;
    for (auto* ptr : obj.ptrs_) { std::cout << *ptr << '\n'; }
}

https://wandbox.org/permlink/rDJw0UU8KcWckLlo

Ответы

Ответ 1

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

Вам разрешено передавать указатель или ссылку на переменную-член в конструктор базового класса, но вы не должны фактически обращаться к объекту в этом конструкторе базового класса.