Подтвердить что ты не робот

Можно ли связать ссылку на еще не сконструированный объект в С++?

Рассмотрим этот пример кода:

class Base {
public:
    Base( string& _object ) : object( _object ) {}
private:
    string& object;
};

class Derived: public Base {
public:
    Derived() : Base( object ) {}
private:
   string object;
};

Очевидно, сначала создается Base, и ему передается ссылка на еще не сконструированный объект.

Память выделяется для всего объекта Derived, поэтому Derived::object находится в законно доступной памяти, только ее конструктор не запускается. Base::Base() не вызывает никаких методов переданного объекта, сохраняет только ссылку. Он работает в Visual С++ 9.

Безопасно ли это в соответствии со стандартом С++?

4b9b3361

Ответ 1

Это безопасно, если вы не "используете" ссылку до создания объекта. Вы можете использовать базовую-и-членную идиому, чтобы переместить объект в (частный) базовый класс, который предшествует базе, и таким образом быть сконструирован перед базой, если вам нужно изменить порядок строительства:

struct Base {
  Base(string &ref) {
    cout << "imagine the ctor uses the ref: " << ref;
  }
};

struct DerivedDetail {
  DerivedDetail(string const &x) : object (x) {}
  string object;
};

struct Derived : private DerivedDetail, Base {
  Derived() : DerivedDetail("foobar"), Base(object) {}
  // In particular, note you can still use this->object and just
  // ignore that it is from a base, yet this->object is still private
  // within Derived.
};

С++ 03 §3.8p6:

... до того, как началось время жизни объекта, но после того, как хранилище, которое будет занимать объект, было выделено или, после того, как срок жизни объекта закончился и перед хранилищем, которое объект занят, повторно используется или освобождается, любая lvalue, которая относится к исходному объекту, но может использоваться только ограниченным образом. Такая lvalue относится к выделенному хранилищу (3.7.3.2) и использует свойства lvalue, которые не зависит от его значения....

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