隐藏复制构造函数 C++

发布于 2024-12-29 20:29:20 字数 977 浏览 0 评论 0原文

我想创建无法复制的类,因此我将复制构造函数放入私有部分:

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

程序编译没有错误,但不调用复制构造函数。所以问题是:如何禁止复制但仍然可以分配数组?

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.
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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情何以堪。 2025-01-05 20:29:20

您的代码 arr [] = { NotCopyable(1,2) }; 确实请求复制构造函数,至少在形式上是这样。实际上,复制通常被省略,但这属于“as-if”规则,并且复制构造函数仍然必须可访问,即使最终不使用它。 (在 GCC 中,您可以说 -fno-elide-constructors 来实际调用复制构造函数。)

您无法在 C++03 中解决这个问题,其中大括号初始化始终需要正式的复制。不过,在 C++11 中,您可以使用大括号初始化来直接初始化数组成员:

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

即使在没有可访问的复制构造函数的情况下,这也可以工作。

Your code 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.)

You can't solve this in C++03, where brace-initialization always necessitates a formal copy. In C++11 you can use brace initialization to direct-initialize array members, though:

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

This works even in the absence of an accessible copy constructor.

对你再特殊 2025-01-05 20:29:20

这是不正确的,因为您使用必须通过复制创建的对象数组:

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

希望这会有所帮助;)

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

木緿 2025-01-05 20:29:20
NotCopyable arr[] =
{
    NotCopyable(1, 0),
    NotCopyable(2, 3)
};

当您编写此代码时,编译器需要复制构造函数,因为它是复制初始化。这就是为什么你会得到编译错误,因为复制构造函数被声明为私有,因此无法从外部访问它。但是,如果您在 public 部分中定义它,那么它可以工作,但复制构造函数不会被调用,这是因为编译器完成了优化。该规范允许编译器在这种情况下省略复制构造函数的调用,但是它仍然需要可访问的复制构造函数,仅用于代码的语义检查。一旦语义检查完成,它实际上就不会被调用!

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

When you write this, the compiler needs copy-constructor, as it is copy-initialization. That is why you get compilation error, as the copy-constructor is declared private, and so it is inaccessible from outside. 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. 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文