将引用绑定到C ++中尚未构造的对象是否安全? [英] Is it safe to bind a reference to a not yet constructed object in C++?

查看:133
本文介绍了将引用绑定到C ++中尚未构造的对象是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑此代码示例:

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

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

显然第一个 Base



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

解决方案

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

它是安全的,只要你在构造对象之前不使用引用。您可以使用基本成员语言将对象移动到如果您需要更改构造顺序,则在Base之前创建一个(私有)基类:Base

  struct Base {
Base(string& ref){
cout<< 想象ctor使用ref:< ref;
}
};

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

struct Derived:private DerivedDetail,Base {
Derived():DerivedDetail(foobar),Base(object){}
//使用this->对象和只是
//忽略它来自一个基础,但是 - >对象仍然是私有的
//在Derived中。
};






C ++ 03§3.8p6:


...在对象的生命周期开始之前,但在对象将占用的存储已经被分配之后,或者在对象的生命周期并且在重新使用或释放​​对象所占用的存储之前,可以使用涉及原始对象的任何左值,但仅以有限的方式。这样的左值指的是分配的存储(3.7.3.2),并且使用不是
的左值的属性取决于它的值是否被明确定义。 ...


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


Consider this code sample:

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

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

Obviously first Base is constructed and it is passed a reference to a not yet constructed object.

Memory is allocated for the whole Derived object, so Derived::object is in legally accessible memory, just its constructor has not run. Base::Base() doesn't call any methods of passed object, only stores the reference. It works in Visual C++ 9.

Is it safe according to C++ Standard?

解决方案

It is safe, as long as you don't "use" the reference before object is constructed. You can use the base-from-member idiom to move object into a (private) base class which comes before Base, and thus be constructed before Base, if you need to change the construction order:

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:

…before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any lvalue which refers to the original object may be used but only in limited ways. Such an lvalue refers to allocated storage (3.7.3.2), and using the properties of the lvalue which do not depend on its value is well-defined. …

In a nutshell: don't access any members, methods, or pass it to anything that does. You can take its address and bind references to it.

这篇关于将引用绑定到C ++中尚未构造的对象是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆