了解构造函数在移动、复制、赋值语义中的行为
Understanding the behavior of constructors in move, copy, assign semantics
这是一个最小的程序,它输出C-tors和D-tors,也是移动/复制操作。
令我感兴趣的是,输出中只有一个 C-tor,尽管在示波器结束时有三个实体被销毁(显示 D-tor(。
那么为什么只显示一个 C-tor ?以及我们如何处理它(显示它们(,或者如果我有误解,我们应该知道什么。
#include <iostream>
class Subject{
public:
Subject(){
std::cout<<"Default C-tor"<<std::endl;
}
Subject(int data):mdata(data){
std::cout<<"C-tor"<<std::endl;
}
virtual~Subject(){
std::cout<<"D-tor"<<std::endl;
}
Subject(Subject const& subject): mdata(subject.mdata){
std::cout<<"Object copied"<<std::endl;
}
Subject& operator=(Subject const& subject){
if(this != &subject){
mdata=subject.mdata;
std::cout<<"Object copied"<<std::endl;
}
return *this;
}
Subject(Subject const&& subject): mdata(std::move(subject.mdata)){
std::cout<<"Object moved"<<std::endl;
}
Subject& operator=(Subject const&& subject){
if(this != &subject){
mdata=std::move(subject.mdata);
std::cout<<"Object moved"<<std::endl;
}
return *this;
}
friend std::ostream& operator<<(std::ostream& out, Subject const& subject){
out<<subject.mdata<<std::endl;
return out;
}
protected:
int mdata;
};
int main()
{
Subject subject{42};
Subject copySubject{subject};
Subject moveSubject = std::move(subject);
return 0;
}
请注意,如果我声明copySubject
和moveSubject
,例如:
Subject copySubject{};
Subject moveSubject{};
它将通过调用默认构造函数来工作。
那么为什么只显示一个 C-tor 呢?
因为您曾经使用过转换 int 构造函数,所以当您在此处直接初始化时:
Subject subject{42};
尽管有三个实体被摧毁
另外两个对象分别是使用复制构造函数和移动构造函数创建的。请注意,这些构造函数都不显示"C-tor"。
您已经定义了三个变量,因此创建和销毁三个对象也就不足为奇了。
附言您的移动赋值和构造函数实际上并没有移动成员,因为您使用了 const 引用作为参数。
相关文章:
- 使用移动和复制语义时函数匹配如何工作?
- 移动语义和深层/浅层复制之间有什么关系?
- 了解构造函数在移动、复制、赋值语义中的行为
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 复制省略并在返回值中移动语义
- 在一个微不足道的可复制结构中,移动语义应该实现吗?
- 在'string=string+s1'和"string+=s1"之间移动语义可以保存多少个复制操作?
- C++复制构造函数和移动语义之间的区别
- 默认情况下,返回是否使用移动或复制语义
- 我应该依赖复制省略还是移动语义
- 在封装指针的类中,移动语义无意中被复制构造函数取代
- 为什么 boost::make_shared 使用复制语义
- 复制有状态分配器:标准库分配器语义和内部内存
- 每次复制实现移动分配的非 const 对象时,我是否总是获得移动语义
- 如何使用C 11移动语义以明确避免复制
- 有没有一种非重复的方法允许程序员在成员初始化的复制和移动语义之间进行选择
- 从具有移动语义或返回值优化的函数返回值,但不返回复制构造函数
- 复制C++唯一指针的语义
- 链表复制/移动语义C++
- C++移动语义:为什么调用复制赋值运算符=(&)而不是移动赋值运算符=(&&)?