zoukankan      html  css  js  c++  java
  • C++的匿名对象

    今天在github看到有人抛出如下异常:throw std::exception("Invalid input."); 即抛出了一个匿名对象。

    就比较了一下c++标准和各平台的实现:https://blog.csdn.net/a3192048/article/details/81329976

    顺便也整理下c++的匿名对象。

    1. C++中的匿名对象是pure RValue, 因而不能作为引用传进去。
    2. 匿名对象只存在于构造该对象的那行代码,离开构造匿名对象的哪行代码后立即调用析构函数。

    例1:

    #include <iostream>
    using namespace std;
    
    class Test
    {
    	int n;
    public:
    	Test(int s) { n = s; }
    	~Test() {
    		cout << "Destructor" << endl;
    	}
    	int ret() { return n; }
    };
    int main()
    {
    	cout << Test(666).ret() << endl; // 匿名对象只存在于该行代码,离开这行代码后立即调用析构函数。
    	cout << "test" << endl;
    	return 0;
    }
    

    输出:

    例2:匿名对象的生命周期

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Teacher
    {
    	string name;
    	string course;
    public:
    	Teacher() {
    		cout << "Default constructor " << endl;
    	}
    	Teacher(const char* n, const char*c) :name(n), course(c) {
    		cout << "constructor " << course << "'s teacher is " << name << endl;
    	}
    	Teacher(const Teacher& t) :name(t.name), course(t.course) {
    		cout << "Copy Constructor " << course << "'s teacher is " << name << endl;
    	}
    	~Teacher() {
    		cout << "Destructor " << course << "'s teacher is " << name << endl;
    	}
    	Teacher& operator=(const Teacher& p)
    	{
    		cout << "Assign" << endl;
    		return *this;
    	}
    };
    int main()
    {
    	Teacher *t5 = new Teacher;  // 或Teacher *t5 = new Teacher(); new没有产生匿名对象,可参考:https://blog.csdn.net/a3192048/article/details/80213288
    	cout << "=======0" << endl;
    	Teacher *t0 = new Teacher("Mr Hu", "Python");
    	cout << "=======1" << endl;
    	Teacher t1("Mr Zhao", "C++");
    	cout << "=======2" << endl; 
    	Teacher t2 = t1;//初始化
    	cout << "=======3" << endl;
    
    	/* 这行代码的运行结果有点“出人意料”,从思维逻辑上说,当匿名对象创建了后,是应该调用自定义拷贝构造函数,或者是默认拷贝构造函数来完成复制过程的,但事实上系统并没有这么做,因为匿名对象使用过后在整个程序中就失去了作用,对于这种情况c++会把代码看成是:
    	Teacher t3("Ms Wang", "Matlab");
    	省略了创建匿名对象这一过程,所以说不会调用拷贝构造函数。 */
    
    	Teacher t3 = Teacher("Ms Wang", "Matlab");//用临时对象来初始化一个新对象,编译器一般会优化成直接用创建临时对象的参数来创建新对象。
    
    	cout << "=======4" << endl;
    	t2 = t3;//不会调用构造函数,因为没有创建新对象,赋值
    	cout << "=======5" << endl;
    	t2 = Teacher("Ms Li", "Consult");//赋值,临时对象会立即释放
    	cout << "=======6" << endl;
    	delete(t5);
    	delete(t0);
    
    	return 0;
    }

    输出:

    例3:

    #include <iostream>
    using namespace std;
    
    class exception
    {
    public:
    	exception()
    	{
    		cout << "Default Constructor" << endl;
    	}
    	exception(const exception& obj)
    	{
    		cout << "Copy Constructor" << endl;
    	}
    	~exception()
    	{
    		cout << "Destructor" << endl;
    	}
    };
    
    /* 注:exception前加::是为了调用全局的exception类,即自定义的exception,而不是库中的! */
    int main()
    {
    	
    	/* 在执行此代码时,利用默认构造函数生成了一个匿名对象;执行完此行代码,
    	因为外部没有接此匿名对象的变量,此匿名又被析构了 */
    	::exception();    // 如改为 ::exception; 则编译不会报错,不会调用构造,析构函数。  
    
        /* 在执行此代码时,利用默认构造函数生成了一个匿名对象;然后将此匿名变成了a这个实例对象,此匿名对象没有被析构。 */
    	::exception a = ::exception();    // 改为 ::exception a = ::exception; 则编译报错!  
    
    	cout << "===========" << endl;
    	
    	return 0;
    }

    输出:

  • 相关阅读:
    小程序 生成二维码
    uni-app调用wifi接口
    微信小程序代码上传,审核发布小程序
    uni-app开发经验分享十五: uni-app 蓝牙打印功能
    面试题 16.11. 跳水板
    LeetCode 63. 不同路径 II
    LeetCode 44. 通配符匹配
    LeetCode 108. 将有序数组转换为二叉搜索树
    LeetCode 718. 最长重复子数组
    LeetCode 814. 二叉树剪枝
  • 原文地址:https://www.cnblogs.com/a3192048/p/12241325.html
Copyright © 2011-2022 走看看