C++理解拷贝控制成员和构造函数

首先通过例子分析:构造函数,拷贝构造函数,拷贝赋值运算符,析构函数:何时调用?

//  定义类Test
class Test
{
public:
    Test(); //默认构造函数 ,由于有其他的构造函数,所以编译器不会合成构造函数;
    Test(const Test &){ std::cout << "Test(const Test &)" << std::endl; } //拷贝构造函数
    Test & operator=(const Test &){ std::cout << "operator=" << std::endl; return *this; } //拷贝赋值运算符
    ~Test();

private:

};

inline Test::Test()
{
    std::cout << "Test()" << std::endl;
}

inline Test::~Test()
{
    std::cout << "~Test()" << std::endl;
}

// 测试函数func ;
Test func(Test t)

//  main 函数
Test a;
Test b = a;
Test c;
c = b;
func(c);

关于inline内联函数说明: C++ Primer P244
1.内联机制用于优化:规模较小,流程直接,频繁调用的函数;
2.类内部定义的成员函数(不是声明)是自动inline的;
3.对于类内部声明的成员函数,要想内联,则在定义时(定义在于类相同的头文件中),前面加关键字inline;

对于上面的程序,输出结果为:
这里写图片描述
分析如下:
Test a //调用默认构造函数
Test b = a //调用拷贝构造函数:因为此处为拷贝初始化,要么调用拷贝构造函数,要么调用移动构造函数;C++ Primer P411
Test c; //调用默认构造函数
c = b; // 调用拷贝赋值运算符 C++ Primer P443
分析func版本1:
func(c);
Test func(Test t) //将一个对象作为实参传递给一个非引用类型的形参,发生拷贝初始化
{
Test x = t; 调用拷贝构造函数
std::cout << “#####” << std::endl;
return x; //从一个返回类型为非引用类型的函数返回一个对象,发生拷贝初始化(此处应该是编译器调用拷贝构造函数生成一个临时对象,从而返回非引用
}
然后开始调用析构函数(从后往前)
第一个输出的 ~Test(),对临时对象的销毁;
第二个,对x对象的销毁;
第三个,对t对象的销毁;

分析func版本2:
输出为:
这里写图片描述
Test& func(Test &t) //传递为引用,不进行拷贝初始化,只是将其值给到t,类似于指针
{
Test x = t; ///调用拷贝构造函数
std::cout << “#####” << std::endl;
return x; // 返回类型为引用(此处有问题,因为传递的是x对象的引用,而x在函数退出之后进行了销毁,但是只为了说明问题),不进行拷贝初始化;
}
然后开始调用析构函数(从后往前)
第一个输出的 ~Test(),对x对象的销毁

分析func版本3:
输出为:
这里写图片描述
Test func(Test &t)
{
Test x = t; //调用拷贝构造函数
std::cout << “#####” << std::endl;
return x; //从一个返回类型为非引用类型的函数返回一个对象
}
然后开始调用析构函数(从后往前)
第一个输出的 ~Test(),对临时对象的销毁;
第二个,对x对象的销毁;

分析func版本4:
输出为:
这里写图片描述
Test func(Test &t)
{
Test *x = new Test; //调用默认构造函数;
std::cout << “#####” << std::endl;
return *x; //从一个返回类型为非引用类型的函数返回一个对象
}
然后开始调用析构函数(从后往前)
第一个输出的 ~Test(),对临时对象的销毁;

分析func版本5:
输出为:
这里写图片描述
Test & func(Test &t)
{
Test *x = new Test;
std::cout << “#####” << std::endl;
delete x; // 调用delete对动态分配的对象x进行销毁,如果你不显示销毁,函数退出作用域也不会销毁动态分配的对象,进行资源释放;
return t;
}
然后开始调用析构函数(从后往前)
第一个输出的 ~Test(),对x对象进行销毁;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态拷贝构造函数(static copy constructor)和移动构造函数(move constructor)是 C++ 中用于对象的复制和移动的特殊成员函数。 拷贝构造函数(copy constructor)用于创建一个新对象,该对象与已经存在的对象具有相同的值。静态拷贝构造函数是指不需要修改成员变量的拷贝构造函数,通常是拷贝成员变量值的过程。 移动构造函数(move constructor)则用于将资源从一个对象转移到另一个对象,通常是在源对象不再被使用时将其资源转移到目标对象,这样可以避免不必要的复制操作,提高性能。移动构造函数通常使用右值引用参数(&&)来接收源对象。 在 C++11 中引入了右值引用和移动语义的概念,允许程序员通过移动语义来提高代码的效率。对于可移动的对象,应该尽可能地使用移动语义来避免不必要的拷贝操作。 如果没有显式定义静态拷贝构造函数或移动构造函数,编译器会自动生成默认的拷贝构造函数和移动构造函数。但如果类中包含了指针成员变量或资源管理类等需要特殊处理的情况,就需要手动定义这两个函数。 请注意,静态拷贝构造函数和移动构造函数是两个不同的概念,静态拷贝构造函数并不具备移动语义。移动构造函数通常会采用右值引用参数,而静态拷贝构造函数则通常采用常量引用参数。 这就是关于静态拷贝构造函数和移动构造函数的一些介绍,希望能对你有所帮助。如果有任何疑问,请随时追问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值