当私有拷贝构造函数带有公共赋值运算符时出错
-
21-09-2019 - |
题
你们中有人能解释一下为什么下面的代码不能编译吗?
#include <iostream>
using namespace std;
class Foo
{
public:
Foo() { cout << "Foo::Foo()" << endl << endl; }
Foo& operator=(const Foo&) { cout << "Foo::operator=(const Foo&)" << endl << endl; }
private:
Foo(const Foo& b) { *this = b; cout << "Foo::Foo(const Foo&)" << endl << endl; }
};
int main()
{
Foo foo;
foo = Foo();
}
我收到的错误:
$ g++ -o copy_ctor_assign copy_ctor_assign.cc && ./copy_ctor_assign
copy_ctor_assign.cc: In function 'int main()':
copy_ctor_assign.cc:10: error: 'Foo::Foo(const Foo&)' is private
copy_ctor_assign.cc:17: error: within this context
笔记:当我删除 私人的: 代码会编译关键字,但永远不会调用复制构造函数。那么为什么当它是私有的时会出错呢?
不确定这是否重要,但我正在使用:
$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
Copyright (C) 2006 Free Software Foundation, Inc.
解决方案
您正在初始化临时引用。
标准规定:
应“使用非引用复制初始化规则 (8.5)”来初始化临时对象(8.5.3 第 5 部分)。
复制结构被临时移除(标准允许)。12.8 标准杆 5)。
然而,该标准明确规定(12.2 par 1):
“即使避免创建临时对象(12.8),也必须遵守所有语义限制,就像创建临时对象一样。[例子:即使不调用复制构造函数,也应满足所有语义限制,例如可访问性(第 11 条)。]”
(另外,在寻找正确的报价时,发现了这个 复制 :)
编辑:从标准中添加相关位置
其他提示
这代码编译用gcc 4.3.3和4.4.1。也许这只是一个错误的GCC 4.1?
假设你已经发布的代码是在项目中唯一的代码,并有FOOS没有秘密路过的价值去任何地方,所有我可以计算是GCC是优化
Foo foo;
foo = Foo();
到
Foo foo = Foo();
...这是不健全,作为第一形式是一个默认的构建体和一个赋值,而第二个是相当于
Foo foo(Foo());
...这显然是一个复制结构。如果我是正确的,拷贝构造函数没有被运行,因为GCC可以优化掉多余的临时的;这是由C ++规范允许的。
在一般情况下,它是不是有赋值运算符,并在不同的保护级别的拷贝构造函数是个好主意;正如你所看到的,其结果可能是不直观的。
Copy Ctor 在以下情况下被调用:
- 按值将对象作为参数传递给函数,
- 从函数返回一个对象。
因此,您肯定会在代码中的某处执行其中一种或两种情况。您应该将 Copy Ctor 设置为公共或避免前面的 2 种情况。
拷贝构造函数会被称为
Foo foo; // normal constructor
Foo foo1(foo); //copy constructor
在您的情况下,首先默认构造函数被调用,然后操作员=方法。
#include <iostream>
using namespace std;
class Foo
{
public:
Foo() { cout << "Foo::Foo()" << endl << endl; }
Foo& operator=(const Foo&) { cout << "Foo::operator=(const Foo&)" << endl << endl; }
Foo(const Foo& b) { *this = b; cout << "Foo::Foo(const Foo&)" << endl << endl; }
};
int main()
{
Foo f1;// default constructor called
Foo f2 = f1; //copy constructor called
}
检查此,在Foo f2=f1;
(使用拷贝构造创建f2
)