简体   繁体   English

隐藏复制构造函数C ++

[英]Hidden copying constructor C++

I would like to create class which can't be copied, so I put copying constructor into the private section: 我想创建无法复制的类,因此我将复制构造函数放入专用部分:

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;
};

Everything is OK except when I would like to assign the array: 一切正常,除了我想分配数组时:

NotCopyable arr[] =
{
    NotCopyable(1, 0),
    NotCopyable(2, 3)
};

The compiler says that she can't access copying constructor as it is in private section. 编译器说她无法访问复制构造函数,因为它在private节中。 When I put it in public section: 当我将其放在公共区域时:

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;
};

Program compiles without errors, but copying constructor isn't called. 程序编译没有错误,但是没有调用复制构造函数。 So the question is: how do I forbid copying but still have possibility to assign arrays? 所以问题是:如何禁止复制但仍然有可能分配数组?

Your code arr [] = { NotCopyable(1,2) }; 您的代码arr [] = { NotCopyable(1,2) }; does request the copy constructor, at least formally. 确实至少在形式上要求复制构造函数。 Practically the copy is usually elided, but that falls under the "as-if" rule, and the copy constructor still has to be accessible, even though ultimately it isn't used. 实际上,通常会删除该副本,但这属于“假设”规则,并且即使最终没有使用副本构造函数,仍然必须可以访问该副本构造函数。 (In GCC you can say -fno-elide-constructors to actually invoke the copy constructor.) (在GCC中,您可以说-fno-elide-constructors实际调用复制构造函数。)

You can't solve this in C++03, where brace-initialization always necessitates a formal copy. 您无法在C ++ 03中解决此问题,因为在括号中初始化总是需要正式的副本。 In C++11 you can use brace initialization to direct-initialize array members, though: 但是,在C ++ 11中,可以使用括号初始化直接初始化数组成员:

NotCopyable arr[] { {1, 0}, {2, 3} };

This works even in the absence of an accessible copy constructor. 即使没有可访问的副本构造函数,此方法也有效。

It is incorrect, because you use array of objects that have to be created by copying: 这是不正确的,因为您使用必须通过复制创建的对象数组:

#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;
}

Since you have disabled copying, you can store reference only. 由于您已禁用复制,因此只能存储参考。 You should make it array of pointers : 您应该使它成为指针数组:

NotCopyable a(1, 2);

// incorrect:
vector<NotCopyable> v;
v.push_back(a);

// correct:
vector<NotCopyable*> v2;
v2.push_back(&a);

Hope this helps ;) 希望这可以帮助 ;)

NotCopyable arr[] =
{
    NotCopyable(1, 0),
    NotCopyable(2, 3)
};

When you write this, the compiler needs copy-constructor, as it is copy-initialization . 在编写此代码时,编译器需要copy-constructor,因为它是copy-initialization That is why you get compilation error, as the copy-constructor is declared private , and so it is inaccessible from outside. 这就是为什么您会得到编译错误的原因,因为copy-constructor被声明为private ,因此无法从外部访问它。 However, if you define it in the public section, then it works, but copy-constructor is not getting called, which is because of the optimization done by the compiler. 但是,如果您在public部分中定义它,则它可以工作,但是不会调用copy-constructor,这是由于编译器进行了优化。 The specification allows the compiler to elide the invocation of the copy-constructor in such situation, however it still needs accessible copy-constructor only for semantic-check of the code. 该规范允许编译器在这种情况下取​​消对复制构造函数的调用,但是它仍然仅需要可访问的复制构造函数来进行代码的语义检查。 It isn't actually called once the semantic check is done! 一旦完成语义检查,它实际上就不会被调用!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM