实现不可复制的C++类
Implementing a non-copyable C++ class
在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;
};
定义代码是,
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;
}
它用于,
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();
}
其中我有意限定了myFoo1
和myFoo2
的定义范围,以便获得对象计数反馈。
当复制构造函数和赋值构造函数public
时,如图所示,编译错误是"C2280 'Foo::Foo(const Foo &(':尝试引用已删除的函数"。当它们成为私有时,编译错误是"C2248 'Foo::Foo':无法访问在类'Foo'中声明的私有成员"。
我相信我误解了原始 SO 答案中的某些内容,但我看不出它是什么。
一切都按预期工作。
您的代码尝试两个副本,并且您为使类不可复制而采用的两种方法都成功了。你可以看到这一点,因为你遇到了编译错误。
如果您不打算在此测试用例中尝试复制,则可能是以下行:
Foo myFoo1{ Foo() };
Foo myFoo2{ Foo("myFoo2") };
在 C++17 之前,这些是副本初始化。如果这不是您的意图,并且您是 C++17 岁之前,那么您应该将它们更改为:
Foo myFoo1{};
Foo myFoo2{"myFoo2"};
或者一个好的老式:
Foo myFoo1;
Foo myFoo2("myFoo2");
同时,你的push_back
肯定是复制的,因为虽然你写了std::move
,但你的类是不可移动的(没有移动构造函数(,所以std::move
实际上什么都不做。
所以:
- 尝试复制对象
- 正在阻止复制
一切都是应该的。
相关文章:
- 简单可复制与可简单复制
- reinterpret_cast,只读访问,简单的可复制类型,会出什么问题?
- 对于参加可复制和可移动类的访问者来说,应该有多少过载?
- 可变参数宏:无法通过"..."传递非平凡可复制类型的对象
- 为什么 std::atomic<std::string> 会给出微不足道的可复制错误?
- 我可以隐式地创建一个琐碎的可复制类型吗
- 是std::memcpy在不同的可复制类型之间的未定义行为
- 为什么一对常量是微不足道的可复制的,而对不是?
- 在一个微不足道的可复制结构中,移动语义应该实现吗?
- 防止作用域枚举可复制/可移动
- C :对象上的可复制视图
- 防御性地应用 std::move 到平凡可复制的类型是否不可取
- 为什么 std::function 本身是可复制构造的类型?
- C++不可复制的 lambda 的行为是可复制的
- 错误:无法通过'...'传递非平凡可复制类型的对象'class boost::filesystem::path'
- 不能让类是微不足道的可复制的。我做错了什么?
- 使用临时存储区复制普通的可复制类型:允许吗
- 使用realloc可以安全地重新分配琐碎的可复制对象的存储吗
- 为什么Boost.Asio处理程序必须是可复制的
- 我需要可复制的缓冲区,尽可能轻(例如,不初始化零)