const、右值引用、临时对象、析构函数的执行时机
来源:互联网 发布:数据维护是做什么 编辑:程序博客网 时间:2024/06/05 06:42
#include <iostream>using namespace std;class Student{private: string _name;public: Student( const char * name) { _name = name; } //= Student( string name) { _name = name; } ~Student() { cout<<"Destructor"<<endl; } //析构函数; void print(const Student &stu){ //某些时候= void print( Student &stu),因为可以将普通的对象绑定 //到const引用,这儿之所以加const,是为了照顾stu5; cout<<"带const参数的print:"<<stu._name<<endl; } void print( Student &stu){ //其实在本程序中= void print(const Student &stu),因为可以将普通的对象 //绑定到const引用,并且函数内部只是读取stu,并不需要更改stu的值; cout<<"带参数(非const)的print:"<<stu._name<<endl; } void print(){ cout<<"不带参数的print:"<<this->_name<<endl; } friend void print(const Student &stu); //声明为友元函数(只需要在普通声明的基础上加friend关键字。 //之所以声明为友元函数,是因为函数是在类外定义的,并且要}; //使用类内的private成员函数;void print(const Student &stu){ //友元函数的定义(也称为实现); cout<<"带参数的print:"<<stu._name<<endl;}int main(){ Student && stu1 = Student("Randy"); //创建无名对象再调用拷贝构造函数初始化"右值引用"; //因为创建临时对象返回的是右值,所以必须用右值引用来绑定; cout<<"stu1:"<<endl; stu1.print(); stu1.print(stu1); cout<<endl; Student stu2("Randy");//= Student stu2 = "Randy";第二种方式涉及到类型的默认转换; //可以认为是string类型通过调用构造函数往Student类型的转换; //但是通常创建对象我们都是使用第一种方式; cout<<"stu2:"<<endl; stu2.print(); stu2.print(stu2); cout<<endl; Student stu3 = Student("Randy"); //通过建立一个临时对象,再赋给"对象stu3"; cout<<"stu3:"<<endl; stu3.print(); stu3.print(stu2); cout<<endl; /*const Student & stu4_0 = Student("Randy"); //编译无法通过;因为此时实参是一个左值引用,再次赋值给形参是不合法的; cout<<"stu4_1:"; stu4.print(); const Student & stu4_1 = Student("Randy"); //编译无法通过;原因同上; cout<<"stu4_1:"; stu4_1.print(stu4_1); */ cout<<"stu5:"<<endl; print(Student("Randy")); //使用临时对象作为函数实参(这时返回的是一个右值),形参一定要 cout<<endl; //加const;因为左值引用不能绑定到返回右值的表达式,见CPPP-P471; cout<<"end of main"<<endl; return 0;}/*通过分别注释stu*的各段函数,发现stu1、stu2、stu3在程序的结束分别调用一次析构函数;所以在end of main语句之 *后输出三个Destructor; *在所有函数之外创建的对象是全局对象,它和全局变量类似,位于内存分区中的全局数据区,程序在结束执行时会调用 *这些对象的析构函数; *在函数内部创建的对象是局部对象,它和局部变量类似,位于栈区,函数执行结束时会调用这些对象的析构函数; * new 创建的对象位于堆区,通过 delete 删除时才会调用析构函数;如果没有 delete,析构函数就不会被执行; [2] */
输出为:
参考:
[1] C++中的临时对象
[2] 析构函数的执行时机
[3] C++ Primer P471介绍了右值引用的使用;P46介绍了普通引用(左值引用)的基本用法;P55介绍了const引用的使用;P534介绍了基类引用可以绑定到派生类的引用;P121介绍了右值和左值的区别,在一般的情况下,左值不能用右值代替,但是右值可以用左值代替;
[4] 关于C++中的临时对象问题
[5] C++中无名对象的作用(程序参考)
阅读全文