8

我有一个类型class A为 的成员变量。_atomicVarstd::atomic<int>

#include <atomic>

class A
{
public:
    A();
    ~A();

private:
    std::atomic<int> _atomicVar;
};

如果我构建项目,我会收到以下错误:

error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)' : attempting to reference a deleted function

我主要是 C# 开发人员,所以我还不了解 C++ 的每一个细节。我不知道我在哪里使用atomic<int>.
我也尝试初始化_atomicVar

std::atomic<int> _atomicVar { 0 };

......但这没有用。
我希望_atomicVar(没有显式初始化)将使用int.
你能告诉我为什么会出现这个错误吗?

4

1 回答 1

15

那是因为 的拷贝构造函数std::atomic删除了。

请参阅此文档页面

由于您没有为 定义显式复制构造函数A,编译器会生成默认的,它只是为所有成员调用复制构造函数(这是不允许的std::atomic)。

解决方案:

class A
{
public:
    A();
    A(const A& origin); // add this line
    ~A();
private:
    std::atomic<int> _atomicVar;
};

A::A(const A& origin)
: _atomicVar(0) //zero-initialize _atomicVar
{
}

编辑

如果您想知道为什么atomic类型不可复制,您可能想阅读这个问题,尤其是接受的答案。如果你想复制 的值std::atomic,你可以这样做:

A::A(const A& origin)
: _atomicVar(origin._atomicVar.load())
{
}

但请记住,此操作本身不会是原子操作(而且,对于大多数逻辑而言,毫无意义)。

此外,您可能还想定义显式赋值运算符(请记住规则三)。

程序正确行为的最佳选择是删除这两种方法:

class A
{
public:
    A();
    A(const A&) = delete;
    ~A();

    A& operator=(const A&) = delete;

private:
    std::atomic<int> _atomicVar;
};

如果您的编译器不支持此功能(例如 VC12 之前的任何 VC),请将它们声明为私有且不提供正文:

class A
{
public:
    A();
    ~A();

private:
    //do not define these two
    A(const A&);
    A& operator=(const A&);

private:
    std::atomic<int> _atomicVar;
};
于 2015-03-29T18:15:24.857 回答