在C ++中插入容器时如何处理非可复制对象 [英] How to deal with noncopyable objects when inserting to containers in 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屋!