C/C++——赋值理解(匿名临时对象)

对三,王炸:

赋值的本质,是将变量传递给一个匿名临时变量,之后再传递给另一个变量。


  •  匿名临时对象:
#include <iostream>
using namespace std;

class A {
public:
    A() {
        cout << "构造函数:" << this << endl;
    }
    A(const A &a) {
        cout << "拷贝构造函数:" << this << endl;
    }
    ~A() {
        cout << "析构函数:" << this << endl;
    }
};

A f() {
    A a;
    return a;
}
int main() {
    A a = f();
    return 0;
}

首先要知道赋值的时候回调用拷贝构造函数,初始化的时候调用构造函数:

执行 return a; 产生了匿名临时对象 F903,在给a的赋值之前,销毁局部对象F803,F903赋值给了外面的a,程序执行结束时销毁。

A()用来创建匿名对象,理论上这也是应该调用拷贝构造函数的,但事实上,编译器会对此进行优化,变成A a;


  •  强制类型转化:

C++属于强类型语言,只要类型不一样,就不能赋值。

但是这里是可以赋值当场打脸,也是因为出现了一个匿名临时对象作为隐式转换的过渡桥梁。

    

注意第二张图:

这里并不是&b开辟了新的空间,引用的就是转换的临时变量

(int &b = a;是报错的)可见临时变量的常量性,const才能引用。

下面这样的隐式转换看似好像是错的。

#include <iostream>
using namespace std;

class A {

public:
    int x;
    A(int num) {
        cout << "构造函数:" << this << endl;
        x = num;
    }
    A(const A &a) {
        cout << "拷贝构造函数:" << this << endl;
    }
    ~A() {
        cout << "析构函数:" << this << endl;
    }
};

int main() {
    A a = 10;
    cout << a.x << endl;
    return 0;
}

两个不同类型能否进行赋值操作,在于能否找到一个中间桥梁,这里的赋值寻找到了构造函数A(int num){};(重载 ‘=’ 运算符也是可以实现的) 所以可以成功,并且a成功实例化。

在构造函数前加上explicit关键字,则禁止 类似这样 不应该允许的经过转换构造函数进行的隐式转换的发生。

加上一个operator int(),反过来也是可以实现的:



C/C++——赋值理解(匿名临时对象)

原文地址:https://www.cnblogs.com/czc1999/p/10323369.html

时间: 2024-10-22 14:38:57

C/C++——赋值理解(匿名临时对象)的相关文章

C++临时对象减少的方法

C++临时对象产生的场景: 1. 值传递   2. 函数返回   3. 后置++ 等 减少临时对象产生的方法: 1. 使用引用或指针传递 2. 避免隐式类型转换 3. 使用 += 代替 + string x = a + b; // 这里会产生保存a+b值的临时对象 string x(a); x += b; // 这样就不会产生临时对象 4. 使用前置++代替后置++ 前置++的定义: type operator++(); 后置++的定义: const type operator++(int);

关于C++临时对象的一道题目

下面的代码输出什么?为什么? class Test { int m_i; int m_j; public: Test(int v) { cout<<"Test(int v)"<<endl; } ~Test() { cout<<"~Test()"<<endl; } }; Test Play(Test t) { return t; } int main() { Test t = Play(5); } 用编译器检测   最后

More Effective C++----(19)理解临时对象的来源

Item M19:理解临时对象的来源 当程序员之间进行交谈时,他们经常把仅仅需要一小段时间的变量称为临时变量.例如在下面这段swap(交换)例程里: template<class T> void swap(T& object1, T& object2) { T temp = object1; object1 = object2; object2 = temp; } 通常把temp叫做临时变量.不过就C++而言,temp根本不是临时变量,它只是一个函数的局部对象.(一切事物皆对象

C++标准的规定:非常量的引用不能指向临时对象(转载)

C++标准的规定:非常量的引用不能指向临时对象: 为了防止给常量或临时变量(只有瞬间的生命周期)赋值(易产生bug),只许使用const引用之. 下面的内容转自: http://blog.csdn.net/liuxialong/article/details/6539717 概括一下: 不能把临时对象作为实参传给非const引用. 例如: void conv(string &str) { } int main() { conv("dasd"); // 这里错了,编译器自动生成一

C++11系列之——临时对象分析

/*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: 1 /**********************************************/ 2 class CStudent; 3 CStudent GetStudent() 4 { 5 CStudent loc_stu; 6 return loc_stu; 7 } 8 9 int main() 10 { 11 CStudent stu = GetStudent(); 12 } 13 /************

消除临时对象

消除临时对象 在我们的代码中,有些临时对象正在使用而我们并未察觉; 性能优化时,消除临时对象,特别是大的临时对象,对提升性能效果明显: 这里列出常见的临时对象产生的地方: 按值返回 按值返回函数结果,结果就是一个临时对象 string add(string s1,string s2) { string s3; s3 = s1+s2; return s3; } 解决方案: 在大多数场景下,这个临时对象可以通过按引用返回来消除: void add(string s1,string s2,string

C++返回对象的问题(临时对象问题)

结论: (1)如果一个类的方法返回一个对象(某个类对象),在使用中均应该将此对象首先赋值给一个局部变量,之后再使用此局部变量.决不能以此临时变量为中间变量再调用其它的. 1,有关 QString::toStdString() 使用的一个细节问题 例子: // 1 ,错误的,cStr的值为非法 QString str = "Hello, world!"; char *cStr = str.toStdString().c_str(); // 2,正确的用法 std::string sstr

如何理解ASP Session 对象

ASP Session 对象 Previous Page Next Page Session 对象用于存储用户的信息.存储于 session 对象中的 变量握有单一用户的信息,并且对于一个应用程序中的所有页面都是可用的. Session 对象 当您操作某个应用程序时,您打开它,做些改变,然后将它关闭.这很像一次对话(Session). 计算机知道您是谁.它清楚您在何时打开和关闭应用程序.但是在因特网上有一个问题: 由于 HTTP 地址无法存留状态,web 服务器并不知道您是谁以及您做什么. AS

一个函数返回临时对象引起的编译器优化问题

我们都知道,如果在一个函数调用另一个函数,假设是 main 函数调用 fun 函数,这个 fun 函数返回一个临时类类型变量,那么这个时候编译器就会在 main 函数申请一个空间并生成一个临时对象,通过拷贝构造函数将 fun 返回的临时变量的值拷贝到这个临时对象.我们看如下的代码: #include <iostream> #include <cstring> using namespace std; class Matrix { public: explicit Matrix(do