本博客是《C++新经典》(王健伟著)的学习笔记,本人是c++初学者,如果有理解错误或者理解不足的地方,还请大神能够指正。
c++搞出了std::move把左值转成右值,还搞出移动构造函数,借此改善性能问题,个人感觉,对我这样的初学者带来一定的理解难度。
我总结了一下,所谓拷贝构造函数在标准上,是深拷贝,为了改善拷贝构造函数带来的成本开销,c++搞出了移动构造函数,本质上就是浅拷贝,综上,其实就是在折腾深浅拷贝而已,其实各有利弊。
1.标准的拷贝构造函数是深拷贝,有对象复制带来的成本开销;
2.拷贝构造函数也可以浅拷贝,但是,总有一种与标准用法不符的感觉;
3.动构造函数,实际就是对浅拷贝的封装,确实减少了对象拷贝带来的成本开销,但是有个重要问题,经过移动构造函数之后,原来我们构造的a对象就不能用了,这个对性能很友好,但是,对程序逻辑的控制带来一些不便,因为,我们一直要分析哪个对象可以用,哪个不可以用。详细请见代码注释;
4.我觉得,很多新特性,我们也不要想那么多,就用最原始的写法,结合对象指针,在堆上创建对象,比较好理解。详细请见代码注释。
#include <iostream>
using namespace std;
class B{
public:
int bn;
B(int n):bn(n){
cout<<"类B的构造函数执行了"<<endl;
};
~B(){
cout<<"类B的析构函数执行了"<<endl;
}
};
class A{
public:
B * a_pb;
A(B * pb):a_pb(pb){
cout<<"类A的有参构造函数执行了"<<endl;
};
~A(){
if(a_pb != nullptr){
delete a_pb;
cout<<"类A的析构函数执行了"<<endl;
}
}
//1.标准的拷贝构造函数是深拷贝,有对象复制带来的成本开销。
A(const A& tmpa):a_pb(new B((*tmpa.a_pb).bn)){
cout<<"类A的拷贝函数执行了"<<endl;
}
//2.下面这段拷贝构造函数也可以执行通过,但是严格意思上,这里是浅拷贝,不是拷贝构造函数。
/*
A(A& tmpa):a_pb(tmpa.a_pb){
tmpa.a_pb=nullptr;
cout<<"类A的拷贝函数执行了"<<endl;
}
*/
//3.下面这个是移动构造函数,实际就是对浅拷贝的封装,确实减少了对象拷贝带来的成本开销
//但是有个重要问题,经过移动构造函数之后,原来我们构造的a对象就不能用了,
//这个对性能很友好,但是,对程序逻辑的控制带来一些不便,
//因为,我们一直要分析哪个对象可以用,哪个不可以用。
A(A&& tmpa):a_pb(tmpa.a_pb){
tmpa.a_pb=nullptr;
cout<<"类A的移动构造函数执行了"<<endl;
}
};
int main(int argc, const char * argv[]) {
A a(new B(2));
cout<<a.a_pb->bn<<endl;
A a1(a);
cout<<a1.a_pb->bn<<endl;
A a2(std::move(a));
cout<<a2.a_pb->bn<<endl;
cout<<"-------------------------"<<endl;
//4.我觉得,很多新特性,我们也不要想那么多,就用最原始的写法,
//结合对象指针,在堆上创建对象,比较好理解。
A* pa= new A(new B(3));
A* pa1=pa;
A* pa2=pa;
cout<<pa->a_pb->bn<<endl;
cout<<pa1->a_pb->bn<<endl;
cout<<pa2->a_pb->bn<<endl;
delete pa;
cout << "Hello, World!\n";
return 0;
}