请考虑以下代码示例:
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 ++标准是否安全?
答案 0 :(得分:19)
只要在构造对象之前不“使用”引用,它就是安全的。您可以使用base-from-member idiom将对象移动到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:
...在对象的生命周期开始之前但是在对象占用的存储空间已经被分配之后,或者在对象的生命周期结束之后以及在对象占用的存储空间被重用或释放之前,任何左值指的是可以使用原始对象但仅限于有限的方式。这样的左值是指分配的存储(3.7.3.2),并使用左值的属性 依赖于它的价值是明确的。 ...
简而言之:不要访问任何成员,方法或将其传递给任何成员。您可以获取其地址并将引用绑定到它。