实现不可复制的 C++ 类

use*_*299 -5 c++ constructor

在 Visual Studio 2019 中,我正在尝试实现使 C++11 显示的类不可复制的技术,后来在如何使这个 C++ 对象不可复制?.

我的课是

class Foo {

public:
    Foo();
    Foo(std::string name);
    ~Foo();

    std::string m_name;

    static std::int32_t s_counter;

public:
    Foo(const Foo& inFoo) = delete;
    Foo& operator=(const Foo& inFoo) = delete;
};
Run Code Online (Sandbox Code Playgroud)

定义代码是,

std::int32_t Foo::s_counter = 0;

Foo::Foo(void)
{
    Foo::s_counter++;
    std::cout << "Foo constructor.  Count = " << Foo::s_counter << std::endl;
}

Foo::Foo(std::string name)
{
    Foo::s_counter++;
    m_name = name;
    std::cout << "Foo " << m_name << " constructor.  Count = " << Foo::s_counter << std::endl;
}

Foo::~Foo()
{
    Foo::s_counter--;
    std::cout << "Foo destructor.  Count = " << Foo::s_counter << std::endl;
}

Run Code Online (Sandbox Code Playgroud)

它用于,

int main(int argc, char** argv) {

    std::vector<Foo> fooVector;

    {
        Foo myFoo1{ Foo() };
        fooVector.push_back(std::move(myFoo1));

        Foo myFoo2{ Foo("myFoo2") };
        fooVector.push_back(std::move(myFoo2));
    }

    if (Foo::s_counter < 0) {

        std::cout << "Foo object count = " << Foo::s_counter << std::endl;
    }

    std::cin.get();
}
Run Code Online (Sandbox Code Playgroud)

其中我有意限定了myFoo1and的定义,myFoo2以便获得对象计数反馈。

当创建复制构造函数和赋值构造函数时public,如图所示,编译错误是“C2280 'Foo::Foo(const Foo &)': 试图引用已删除的函数”。将它们设为私有时,编译错误为“C2248 'Foo::Foo': 无法访问类 'Foo' 中声明的私有成员”。

我相信我误解了原始 SO 答案中的某些内容,但我看不到它是什么。

Lig*_*ica 6

一切都按预期工作。

您的代码尝试了两个副本,并且您使类不可复制的两种方法都成功了。您可以看到,因为您遇到了编译错误。

如果您不打算在此测试用例中尝试复制,则可能是以下几行:

Foo myFoo1{ Foo() };
Foo myFoo2{ Foo("myFoo2") };
Run Code Online (Sandbox Code Playgroud)

在 C++17 之前,那些是复制初始化。如果这不是您想要的,并且您是 C++17 之前的,那么您应该将它们更改为:

Foo myFoo1{};
Foo myFoo2{"myFoo2"};
Run Code Online (Sandbox Code Playgroud)

......或者一个很好的老式:

Foo myFoo1;
Foo myFoo2("myFoo2");
Run Code Online (Sandbox Code Playgroud)

同时,您的push_backs 绝对是副本,因为尽管您编写了 ,但您std::move的类不可移动(没有移动构造函数),因此std::move实际上什么也不做。

所以:

  1. 尝试复制对象
  2. 正在阻止复制

一切都应该如此。

  • 好吧,我想我们是被骗了。我出去了... (4认同)