在C ++中插入容器时如何处理非可复制对象 [英] How to deal with noncopyable objects when inserting to containers in C++

查看:179
本文介绍了在C ++中插入容器时如何处理非可复制对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找处理非可复制对象的最佳实践。



我有一个互斥体类,显然不应该是可复制的。
我添加了一个私人复制构造函数来强制执行。



破坏了代码 - 一些地方只是需要修复,但我有一个通用的问题
其中一个类,使用互斥量作为数据成员或继承,被插入到容器中。



这通常在容器初始化期间发生,因此互斥体尚未初始化,因此确定,但没有副本构造函数,它不工作。

解决方案



<

这里有三个解决方案:



1。使用指针 - 快速修复是使它成为指针的容器 - 例如。 a shared_ptr



如果你的对象真正不可复制,是不可能的。



2。其他容器 - 或者,您可以使用非复制容器(使用in-place-construction),但是它们并不常见,并且与STL基本不兼容。 (我已经尝试了一段时间,但它根本没有好处)



这将是神解决方案,如果你的对象是真正的不可复制的,并且使用指针不是可能。



使用C ++ 13,std :: vector允许inplace构造(emplace_back),并且可以用于实现move语义的非可复制对象。
[/ edit]



3。修复您的可复制性 - 如果您的类是可复制的,并且互斥不是,您简单地需要修复复制构造函数和赋值运算符。



写它们是一种痛苦,因为你通常必须复制&分配除了互斥体之外的所有成员,但通常可以通过以下简化:

 模板< typename TNonCopyable> 
struct NeverCopy:public T
{
NeverCopy(){}
NeverCopy(T const& rhs){}

NeverCopy< T& & operator =(T const& rhs){return * this; }
}

将您的mutex成员更改为

  NeverCopy< Mutex> m_mutex;不幸的是,使用那个模板你失去了Mutex的特殊构造函数。


$


警告:修复复制CTor / asignment通常需要您在副本构造上锁定右侧,并在分配时锁定两侧。很遗憾,无法覆盖复制ctor / assignment 调用默认实现,因此 NeverCopy 技巧可能无法在没有外部锁定。 (还有一些其他的解决方法,有自己的限制。)


I'm looking for the best-practice of dealing with non-copyable objects.

I have a mutex class, that obviously should not be copyable. I added a private copy constructor to enforce that.

That broke the code - some places simply needed to be fixed, but I have a generic problem where a class, using the mutex either as a data member, or by inheritance, is being inserted into a container.

This is usually happening during the container initialization, so the mutex is not initialized yet, and is therefore ok, but without a copy constructor it does not work. Changing the containers to contain pointers is not acceptable.

Any advise?

解决方案

Three solutions here:

1. Use Pointers - The quick fix is to make it a container of pointers - e.g. a shared_ptr.

That would be the "good" solution if your objects are truly noncopyable, and using other containers is not possible.

2. Other containers - Alternatively, you could use non-copying containers (that use in-place-construction), however they aren't very common and largely incompatible with STL. (I've tried for a while, but it's simply no good)

That would be the "god" solution if your objects are truly noncopyable, and using pointers is not possible.

[edit] With C++13, std::vector allows inplace construction (emplace_back), and can be used for noncopyable objects that do implement move semantics. [/edit]

3. Fix your copyability - If your class is copyable as such, and the mutex is not, you "simply" need to fix the copy constructor and assignment operator.

Writing them is a pain, since you usually have to copy & assign all members except the mutex, but that can often be simplified by:

template <typename TNonCopyable>
struct NeverCopy : public T 
{
    NeverCopy() {}
    NeverCopy(T const & rhs) {}

    NeverCopy<T> & operator=(T const & rhs) { return *this; }
}

And changing you mutex member to

NeverCopy<Mutex> m_mutex;

Unfortunately, using that template you lose special constructors of Mutex.

[edit] Warning: "Fixing" the Copy CTor/asignment often requires you to lock the right hand side on copy construct, and lock both sides on assignment. Unfortunately, there is no way to override the copy ctor/assignment and call the default implementation, so the NeverCopy trick might not work for you without external locking. (There are some other workarounds with their own limitations.)

这篇关于在C ++中插入容器时如何处理非可复制对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆