我想创建无法复制的类,所以我将复制构造函数放入私有部分:
class NotCopyable
{
public:
NotCopyable(const double& attr1, const double& attr2) : _attr1(attr1), _attr2(attr2) {}
~NotCopyable(void) {}
private:
NotCopyable& operator=(const NotCopyable&);
NotCopyable(const NotCopyable&);
double _attr1;
double _attr2;
};
除非我想分配数组,否则一切正常:
NotCopyable arr[] =
{
NotCopyable(1, 0),
NotCopyable(2, 3)
};
编译器说她无法访问复制构造函数,因为它在私有部分中。 当我把它放在公共区域时:
class NotCopyable
{
public:
NotCopyable(const double& attr1, const double& attr2) : _attr1(attr1), _attr2(attr2) {}
~NotCopyable(void) {}
NotCopyable(const NotCopyable&)
{
std::cout << "COPYING" << std:: endl;
}
private:
NotCopyable& operator=(const NotCopyable&);
double _attr1;
double _attr2;
};
程序编译没有错误,但不调用复制构造函数。所以问题是:我如何禁止复制但仍有可能分配数组?
答案 0 :(得分:7)
您的代码arr [] = { NotCopyable(1,2) };
确实请求复制构造函数,至少是正式的。实际上,副本通常被省略,但这属于“as-if”规则,并且复制构造函数仍然必须是可访问的,即使最终它没有被使用。 (在GCC中,您可以说-fno-elide-constructors
实际调用复制构造函数。)
你无法在C ++ 03中解决这个问题,其中大括号初始化总是需要正式的副本。在C ++ 11中,您可以使用大括号初始化来直接初始化数组成员,但是:
NotCopyable arr[] { {1, 0}, {2, 3} };
即使没有可访问的复制构造函数,也可以使用。
答案 1 :(得分:1)
这是不正确的,因为您使用必须通过复制创建的对象数组:
#include <vector>
using namespace std;
class NotCopyable
{
public:
NotCopyable(const double& attr1, const double& attr2) : _attr1(attr1), _attr2(attr2) {}
~NotCopyable(void) {}
private:
NotCopyable& operator=(const NotCopyable&);
NotCopyable(const NotCopyable&);
double _attr1;
double _attr2;
};
int main()
{
vector<NotCopyable> v;
NotCopyable a(1, 2);
v.push_back(a); // THIS IS COPYING
return 0;
}
由于您已禁用复制,因此您只能存储参考。你应该把它作为指针:
的数组NotCopyable a(1, 2);
// incorrect:
vector<NotCopyable> v;
v.push_back(a);
// correct:
vector<NotCopyable*> v2;
v2.push_back(&a);
希望这会有所帮助;)
答案 2 :(得分:0)
NotCopyable arr[] =
{
NotCopyable(1, 0),
NotCopyable(2, 3)
};
编写时,编译器需要copy-constructor,因为它是 copy-initialization 。这就是为什么你得到编译错误,因为复制构造函数被声明为private
,因此它无法从外部访问。但是,如果在public
部分中定义它,那么它可以工作,但是不会调用copy-constructor,这是因为编译器完成了优化。规范允许编译器在这种情况下忽略复制构造函数的调用,但是它仍然需要 accessible 复制构造函数,仅用于代码的语义检查。一旦完成语义检查,它就不会被调用!