lin*_*bin 1 c++ move shared-ptr c++11
在C++ move11/14中,对象可以通过或者smark指针传输.
(1)这是一个例子move:
class MoveClass {
private:
int *tab_;
int alloc_;
void Reset() {
tab_ = nullptr;
alloc_ = 0;
}
void Release() {
if (tab_) delete[] tab_;
tab_ = nullptr;
alloc_ = 0;
}
public:
MoveClass() : tab_(nullptr), alloc_(0) {}
~MoveClass() {
Release();
}
MoveClass(MoveClass && other) : tab_( other.tab_ ), alloc_( other.alloc_ ) {
other.Reset();
}
MoveClass & operator=(MoveClass && other) {
if (this == &other) return *this;
std::swap(tab_, other.tab_);
std::swap(alloc_, other.alloc_);
return *this;
}
void DoSomething() { /*...*/ }
};
Run Code Online (Sandbox Code Playgroud)
当我们使用这个可移动的时候MoveClass,我们可以写这样的代码:
int main() {
MoveClass a;
a.DoSomething(); // now a has some memory resource
MoveClass b = std::move(a); // move a to b
return 0;
}
Run Code Online (Sandbox Code Playgroud)
总是写move-constructor/move-operator =很无聊,使用shared_ptr/unique_ptr有时会产生相同的效果,就像java,reference/pointer到处都是.
(2)这是一个例子:
class NoMoveClass {
private:
int *tab_;
int alloc_;
void Release() {
if (tab_) delete[] tab_;
tab_ = nullptr;
alloc_ = 0;
}
public:
NoMoveClass() : tab_(nullptr), alloc_(0) {}
~NoMoveClass() {
Release();
}
MoveClass(MoveClass && other) = delete;
MoveClass & operator=(MoveClass && other) = delete;
void DoSomething() { /*...*/ }
};
Run Code Online (Sandbox Code Playgroud)
我们可以像这样使用它:
int main() {
std::shared_ptr<NoMoveClass> a(new NoMoveClass());
a->DoSomething();
std::shared_ptr<NoMoveClass> b = a; // also move a to b by copy pointer.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
总是使用第二个是一个好习惯吗?
为什么很多图书馆,STL使用第一个,而不是第一个?
总是写move-constructor/move-operator =很无聊
你几乎不需要编写自己的移动构造函数/赋值,因为(正如你所提到的)C++为你提供了许多基本的资源管理器 - 智能指针,容器,智能锁等.
通过依赖类中的那些,您可以启用默认移动操作,从而产生最小的代码大小以及正确的语义:
class MoveClass {
private:
std::vector<int> data;
public:
void DoSomething() { /*...*/ }
};
Run Code Online (Sandbox Code Playgroud)
现在您可以像在(1)中一样使用您的类,或者在其他类中使用您的类,您可以确定它具有移动语义,并且您可以在尽可能少的代码中完成它.
关键是通常只需要为STL可能已经涵盖的最低级别的类实现移动操作,或者如果需要一些奇怪的特定行为 - 两种情况都应该非常罕见并且不会导致"始终写入移动 - 构造/移动运营商=".
还要注意虽然方法(1)是不必要的冗长,但(2)只是不可接受 - 你有一个资源管理类不能完成它的工作,因此你必须将它包装在代码中的任何地方的智能指针中,它更难理解并最终产生比(1)更多的代码
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |