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

3

我试图运行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;
}

这是因为书中的代码不正确,而非有什么魔法。建议进行修改。谢谢。


@Koushik,G++ 4.7.3。我在Windows上使用cygwin,它支持g++最高版本为4.7.3。 - zyangpointer
4
VC++不支持统一初始化语法(用“花括号”进行初始化),而g ++ / clang 可以,但它们需要在命令行中加入“-std=c++11”。 - Casey
2
@zyangpointer,你的编译器错误信息是什么,确切地说?你是如何精确地编译程序的? - OmnipotentEntity
2
@zyangpointer,请编辑问题以删除歧义。您可以使用此代码,它完整地描述了您的问题。 - awesoon
@soon,谢谢,我已经按照你的建议更改了问题标题。 - zyangpointer
显示剩余6条评论
2个回答

6

1
在线 delete y.p; 之后,由 x.py.p 指向的内存被释放了。因此,x.p 现在指向已释放的内存。

y.p = new int{3}; 这一行代码之后,指针 y.p 已被重新赋值,所以 x.py.p 不再指向同一块内存。

x.p 仍然指向 delete 行释放的那块内存,因此尝试对其进行解引用时会导致段错误。


澄清一下:在 y.p 被重新分配后,x.py.p 可能 指向同一块内存,如果内存分配在相同的地址上。示例。这是未定义行为,此代码可能会导致段错误,也可能不会。但答案是正确的,+1。 - awesoon
这不是被问到的问题...被问到的问题与编译错误有关。 - OmnipotentEntity
@OmnipotentEntity,我不这么认为。问题中引用的内容是:“...但没有将结果输出为注释,我哪里错了?”此外,标题是:“...似乎无效”,而不是“...似乎无法编译”。 - awesoon
我可能高估了OP,但问题实际上包含在程序注释中发布的答案...此外,他特别指出了代码的一部分,即他不理解/遇到麻烦的大括号初始化复制构造函数... - OmnipotentEntity
@OmnipotentEntity 我认为自从我发布答案以来,它已经被编辑过了,OP最初没有明确指出问题是什么。 - maditya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接