临时对象构造函数和析构函数的执行时机

时间:2022-04-21 04:29:53
//主要介绍构造函数和析构函数;

#include <iostream>

using namespace std;

class Student
{
private:
string _name;

public:
Student( const char * name) { //形参也可以这么写: Student( string name) {....}
_name = name;
cout<<"Cnstructor"<<endl;
}

Student( const Student & STU) {_name = STU._name; cout<<"Copy Function"<<endl;} //拷贝构造函数;
~Student() { cout<<"Destructor "<<endl; } //析构函数;

void print(Student stu){ //某些时候= void print( Student &stu),因为其实是可以将普通的对象绑定到const引用
cout<<"带参数的print:"<<stu._name<<endl;
}
void print(){
cout<<"不带参数的print:"<<this->_name<<endl;
}
friend void print1( Student stu); //声明为友元函数(只需要在普通声明的基础上加friend关键字。
//之所以声明为友元函数,是因为函数是在类外定义的,并且要
}; //使用类内的private成员函数;

void print1( Student stu){ //友元函数的定义(实现);
cout<<"带参数的print:"<<stu._name<<endl;
}

int main()
{
Student stu1("Randy");
cout<<"stu1:"<<endl;
stu1.print();
stu1.print(stu1); //以值的方式为函数传参,需要值的拷贝,也即是调用拷贝构造函数;
cout<<endl;

Student stu2 = Student("Randy"); //此时相当于Student stu2(Randy)来调用构造函数;见[1]
cout<<"stu2:"<<endl;
stu2.print();
stu2.print(stu2); //调用拷贝构造函数;
cout<<endl;

cout<<"stu3:"<<endl;
print1(Student("Randy")); //使用友元print函数,使用临时对象作为函数实参(这时返回的是一个右值),形参有三种选择:
cout<<endl; //①如本例,采用值传递的方式:Student stu;
//②使用引用:const Student & stu;此时的const不能少,因为实参是右值,见C++ Primer-P471;
//③使用右值引用:Student && stu;


Student stu4(stu1); //使用拷贝构造函数;打印Copy Function;
cout<<"stu4:"<<endl;
stu4.print();
stu4.print(stu4); //再次调用拷贝构造函数;
cout<<endl;

cout<<"end of main"<<endl;

return 0;
}

/*通过分别注释stu*的各段函数,发现stu1、stu2、stu4在程序的结束分别调用一次析构函数;所以在end of main语句之
*后输出三个Destructor;
*在所有函数之外创建的对象是全局对象,它和全局变量类似,位于内存分区中的全局数据区,程序在结束执行时会调用
*这些对象的析构函数;
*在函数内部创建的对象是局部对象,它和局部变量类似,位于栈区,函数执行结束时会调用这些对象的析构函数;
* new 创建的对象位于堆区,通过 delete 删除时才会调用析构函数;如果没有 delete,析构函数就不会被执行;
*/

输出为:

临时对象构造函数和析构函数的执行时机


参考:

[1] C++中的临时对象