【发布时间】:2017-10-31 16:40:40
【问题描述】:
在 C++11/14 中,可以通过move 或 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() { /*...*/ }
};
当我们使用这个可移动的MoveClass时,我们可以这样写代码:
int main() {
MoveClass a;
a.DoSomething(); // now a has some memory resource
MoveClass b = std::move(a); // move a to b
return 0;
}
总是写move-constructor/move-operator=很无聊,用shared_ptr/unique_ptr有时候效果一样,就像java一样,到处都是引用/指针。
(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() { /*...*/ }
};
我们可以这样使用它:
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;
}
总是使用第二个是个好习惯吗?
为什么很多库,STL 使用第一个,而不是第一个?
【问题讨论】:
-
在您的第一个示例中,MoveClass 位于堆栈上,第二个示例位于堆上。在堆上分配所有内容并使用智能指针会带来很大的开销。更不用说语义不同了。
-
@KinanAlSarmini 堆上的 'tab_' 和 'alloc_' 会花费这么多吗?有没有性能基准数据?
-
@zhaochenyou 一个额外的间接性肯定会花费一些东西,但关键是语义不同,这两种技术不可互换
-
@Ap31 是的,有时候,我只是想少写一些代码
-
C++ 让您可以随心所欲。如果您发现这适合您的需求,并且性能成本对于 您的 应用程序来说微不足道,那就去吧。
标签: c++ c++11 shared-ptr move