为什么我不能使用大括号括起初始化列表来调用复制构造函数?

时间:2013-07-30 04:13:30

标签: c++11

我试图运行Bjarne Stroustrup编写的新C ++编程语言书中的代码似乎不起作用。哪个编译器支持代码中的语法S y {x};?无法编译,我试过g ++,vc ++,还没有Clang,那个错误代码假设是初始化,之后,我把那个代码更改为S y = x;一个赋值,但没有输出结果作为注释,我错了某处?

struct S {
     int* p;    // a pointer
};

S x {new int{0}};
void f()
{
     S y {x};              // "copy" x

     *y.p = 1;             // change y; affects x
     *x.p = 2;             // change x; affects y
     delete y.p;           // affects x and y
     y.p = new int{3};     // OK: change y; does not affect x
     *x.p = 4;             // oops: write to deallocated memory
}

然后我重写了C ++ 03版本的代码,它的工作原理如下:

struct S
{
    int *p;  
};

int main()
{
   S x;
   x.p = new int;
   *(x.p) = 0;

   S y = x;
   *y.p = 1;
   *x.p = 2;
   delete y.p;
   y.p = NULL;
   x.p = NULL;
   y.p = new int;
   *(y.p) = 3;
   *(x.p)= 4;
}

是否有任何魔法,或者只是书中的代码不正确。任何建议谢谢。

2 个答案:

答案 0 :(得分:6)

这是C ++ 11措辞的已知问题。 C ++ 14 CD也没有解决此问题(请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1467了解相应的DR)。

我们希望编译器可以追溯性地在C ++ 11和C ++ 14模式下实现此功能。下一期问题清单修订应包含问题1467的建议措辞,以解决此问题。

答案 1 :(得分:1)

在行delete y.p;之后,x.py.p指向的内存被释放。因此x.p现在指向释放的内存。

在行y.p = new int{3};之后,x.p和y.p不再指向同一个内存,因为指针 y.p已被重新分配。

x.p仍然指向delete行的释放内存,因此当您尝试取消引用它时会出现seg错误。