Безопасно ли связывать ссылку на еще не сконструированный объект в C ++? - PullRequest
20 голосов
/ 27 января 2011

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

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 C ++ 9.

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

1 Ответ

19 голосов
/ 27 января 2011

Это безопасно, пока вы не «используете» ссылку до того, как объект будет создан.Вы можете использовать идиому base-from-member , чтобы переместить объект в (частный) базовый класс, который предшествует Base, и, таким образом, будет создан до Base, если вам нужно изменить порядок построения:

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.
};

C ++ 03 §3.8p6:

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

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

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