在C ++ 11中重置结构值

时间:2019-04-06 08:52:24

标签: c++ c++11

好像已经问过几次这个问题,但根据现有的答案和指导,我似乎无法使其正常工作。

代码如下:

#include <atomic>

class X
{
  public:
    X();
    ~X();
    void alpha();
  private:
    struct A {
      bool m;
      std::atomic<bool> n;
      bool fish();
    };
    A aval_;
};

X::X() : aval_() {}
X::~X() {}

bool X::A::fish() {
  return true;
}

void X::alpha() {
  aval_.m = false;
  aval_ = {};
}
  

'X :: A'类型的对象无法分配,因为其副本分配运算符被隐式删除

我应该覆盖一些东西吗?我通常不是C ++程序员,所以请随时将我指向可以学习更多知识的资源。

编辑:更新了源代码以包括std::atomic<bool>

1 个答案:

答案 0 :(得分:2)

原因是因为std::atomic没有默认的复制构造函数。尝试以下代码:

std::atomic<bool> v1(false);
std::atomic<bool> v2  = v1;

您应该得到的错误是:

error: call to implicitly-deleted copy constructor of 'std::atomic<bool>'
    std::atomic<bool> n2  = n1;
                      ^     ~~
note: copy constructor of 'atomic<bool>' is implicitly deleted because base class '__atomic_base<bool>' has a deleted copy constructor

note: '__atomic_base' has been explicitly marked deleted here
    __atomic_base(const __atomic_base&) = delete;

如果这样做的唯一目的是重置A的成员,则只需创建一个重置函数void reset()并将成员重置为其初始值即可。

void reset()
{
    m = false;
    n = false;
}

然后在void alpha()中执行:

void alpha()
{
    aval.m = false;
    aval.reset();
}

以上是计划A 。作为计划B ,您可以使用智能指针(std::unique_ptr)来保存aval。然后,您可以简单地reset指针。

所以不要使用堆栈:

A aval;

您使用堆:

    ...
    std::unique_ptr<A> aval;

public:
    X() : aval(std::make_unique<A>())
    {;}

    void alpha()
    {
        aval->m = false;
        aval.reset(new A());
    }

我个人喜欢第一种方法。考虑以下事实:无论构造器的名称为“ constructor”如何,构造器都不会构造任何东西。它所做的只是初始化类的成员。这正是reset()的工作,并且您使用堆栈。