在C++中绑定对尚未构造的对象的引用是否安全?

sha*_*oth 20 c++ reference visual-c++

考虑以下代码示例:

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

class Derived: public Base {
public:
    Derived() : Base( object ) {}
private:
   string object;
};
Run Code Online (Sandbox Code Playgroud)

显然首先Base构造并传递对尚未构造的对象的引用.

内存是为整个Derived对象分配的,因此Derived::object在合法可访问的内存中,只是它的构造函数没有运行.Base::Base()不调用任何传递对象的方法,只存储引用.它适用于Visual C++ 9.

根据C++标准,它是否安全?

Fre*_*urk 19

它是安全的,只要你在构造对象之前不"使用"引用.您可以使用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.
};
Run Code Online (Sandbox Code Playgroud)

C++03§3.8p6:

...在对象的生命周期开始之前,但在对象占用的存储空间已经分配之后,或者在对象的生命周期结束之后,在对象占用的存储空间被重用或释放之前,任何左值引用可以使用原始对象,但仅限于有限的方式.这样的左值是指分配的存储(3.7.3.2),并且使用不依赖于其值的左值的属性是明确定义的....

简而言之:不要访问任何成员,方法或将其传递给任何成员.您可以获取其地址并将引用绑定到它.