Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否使用“新放置”更新引用成员? C++中的下面代码是合法的吗?_C++_Reference_Object Lifetime_Placement New_Reference Binding - Fatal编程技术网

是否使用“新放置”更新引用成员? C++中的下面代码是合法的吗?

是否使用“新放置”更新引用成员? C++中的下面代码是合法的吗?,c++,reference,object-lifetime,placement-new,reference-binding,C++,Reference,Object Lifetime,Placement New,Reference Binding,template<typename T> class Foo { public: Foo(T& v) : v_(v) {} private: T& v_; }; int a = 10; Foo<int> f(a); void Bar(int& a) { new (&f)Foo<int>(a); } 模板 福班{ 公众: Foo(T&v):v_v(v){} 私人: T&v; }; INTA=10;

template<typename T>
class Foo {
public:
    Foo(T& v) : v_(v) {}

private:
    T& v_;
};

int a = 10;
Foo<int> f(a);

void Bar(int& a) {
    new (&f)Foo<int>(a);
}
模板
福班{
公众:
Foo(T&v):v_v(v){}
私人:
T&v;
};
INTA=10;
傅f(a),;
空栏(内部和外部){
新(甲)富(甲);;
}

引用不应该被绑定两次,对吗?

它可能是合法的,但它的风格非常糟糕。放置new的参数是空洞*,因此你告诉C++重新解释f的地址,作为一个空洞*,然后使用它作为构建新事物的位置-重写原来的F.< /P>
基本上,不要这样做。

这是完全无效的

[基本生活]/1,强调我的:

类型为
T
的对象的生存期在以下情况下结束:

  • 如果
    T
    是具有非平凡析构函数(12.4)的类类型,则析构函数调用将启动,或者
  • 对象占用的存储被重新使用或释放。
新的放置重用了存储,结束了由
f
表示的对象的生命周期

[基本生活]/7:

如果,在对象的生存期结束后和存储之前 当被占用的对象被重用或释放时,将创建一个新对象 在原始对象所占用的存储位置创建的 指向原始对象的指针,引用 到原始对象,或原始对象的名称将 自动引用新对象,并在 新对象已启动,可用于操纵新对象,如果:

  • 新对象的存储正好覆盖原始对象占用的存储位置,并且
  • 新对象与原始对象的类型相同(忽略顶级cv限定符),并且
  • 原始对象的类型不是const限定的,如果是类类型,则不包含任何类型为的非静态数据成员 常量限定或引用类型,以及
  • 原始对象是
    T
    类型的最派生对象(1.8),而新对象是
    T
    类型的最派生对象(即,它们是 不是基类子对象)
由于第三个项目符号未得到满足,在调用
Bar
后,
f
不引用通过放置
new
创建的对象,而是引用以前不再存在的对象,尝试使用它会导致未定义的行为


另请参见和。

您没有绑定引用
v\ucode>两次,而是使用
Foo(a)
Bar
中初始化的对象中的数据覆盖它。“引用不应该绑定两次,对吧?”–不,但这与您的其余问题有什么关系?@JoachimPileborg谢谢,现在我回头看,最后一句话毫无意义。引用不能绑定两次,我们不能做任何事情来重新绑定引用。为什么不呢?它是完全类型安全的。C++中几乎没有什么是“完全类型安全”的。C++不真正知道这个词的意思。如果Foo是使用复杂类型实例化的呢?甚至一根绳子?reinterpret_cast会覆盖对象的构造内容。好的,在几乎所有的实际情况下,您都需要这里的赋值运算符,它将正确地销毁复杂类型。也就是说,对于普通的旧数据或调用了析构函数的对象来说,这是很好的。换句话说,C++让你再次在你的脚上开枪。即使是,如果你已经正确地定义了它(或者它是POD,你不需要一个),赋值操作符也就OK了。默认的只是覆盖对象。如果正确定义,任何事情都会正常工作。是的,默认赋值运算符可能会在一些写得不好的类上失败。我不明白什么。在placement new指令中:创建新对象不意味着重新利用对象占用的存储空间吗?在这种情况下,对我来说,新的放置之后,不满足条件:“在对象占用的存储被重用或释放之前”,因为f的未来使用发生在存储被重用之后。我不明白这些规则是如何组合起来的。