【问题标题】:Copy constructor with named object使用命名对象复制构造函数
【发布时间】:2016-06-12 21:59:41
【问题描述】:

这是我的代码:

class A {
int x;
public:
    A(int p) {cout << "constructor\n"; }
    A(const A& p) { cout << "copy constructor\n";}
    A& operator=(const A& p) { cout << "assignment\n"; return *this;}
    ~A() {cout << "destructor\n";}
};  

A foo(){ A temp(3); return temp;}

int main()
{
    A a(1);
    A b = A(2);
    A c = foo();
    //A d = A e(4);   This one doesn't work!
}

我知道匿名对象(未命名对象)具有“表达式范围”,这意味着它们在创建它们的表达式的末尾被销毁。这意味着,在我们的代码中,未命名的对象一直存在到分号。

在 12.2/3 中有说明:

临时对象在评估完整表达式 (1.9) 的最后一步时被销毁,该完整表达式 (从词法上) 包含它们的创建点。

所以,我知道命名对象和未命名对象在范围方面是不同的。

我的问题是为什么最后一行代码不起作用?作用域与它有什么关系吗?
而为什么A c = foo(); 起作用,看到右手边也是一个命名对象?

【问题讨论】:

  • 您希望发生什么?
  • 我希望它能与 `A d = A e(4);参与。
  • 那是错误的。可能类似于使用声明语句作为表达式,但我不是真正的语法人。
  • @flatmouse:我不愿将国际专家委员会的标准化结果称为“教条”,但 WG21 会议和尼西亚委员会之间的相似之处很难消除。提案、研究小组、民意调查、措辞审查……我想不同之处在于标准可以更改,错误的实施者不会被逐出教会。
  • foo() 不是命名对象

标签: c++ constructor copy-constructor


【解决方案1】:

初始化需要右侧的表达式。 A e(4) 不是表达式,而是声明。它没有值。

【讨论】:

  • 那么,A e(4) 不是表达式,但 A(4) 是?
  • 完美地回答了我的问题。谢谢!
【解决方案2】:
//A d = A e(4);   This one doesn't work!

这只是无效的语法。你不需要e,它甚至没有在任何地方被进一步引用。

你的陈述应该是这样的

A d = A(4);

A d(4);

【讨论】:

  • 这个问题已经有正确语法的例子。问题是为什么它是错误的。
  • @flatmouse “为什么错了。” 正如回答,它是无效的语法。除了这个事实,你还想读什么?我愿意改进我的答案。
  • 我认为这是一个语言律师类型的问题。类似于为什么声明不能成为表达的一部分的问题可能是一个明确的答案。
  • 你只是在重复这个问题,没有新的信息。不公平。
  • @KennyOstrom 不是真的,关于范围和名称等的问题仍在继续,但这与问题无关,即 语法错误
【解决方案3】:

您可以使用A d = a; 来调用您的复制构造函数。 这个案例A c = foo();被编译器简化为这个案例A b = A(2);,因为右侧的实体在赋值后停止生存,它可以简单地使用右侧而不是左侧。

【讨论】:

  • 实际上,我说的是返回值优化禁用了代码的执行,其输出为:构造函数构造函数复制构造函数析构函数构造函数复制构造函数析构函数复制构造函数析构函数析构函数析构函数析构函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
相关资源
最近更新 更多