kanlian4095 2020-08-24 11:15 采纳率: 80%
浏览 239
已采纳

C++当函数返回值为类类型时 作为左值的疑问

#include
using namespace std;

//定义类

class Person
{
private:
int m_Age;
public:

//定义默认构造函数

Person()

{

cout << "默认构造函数!" << endl;

}

//定义有参构造函数
Person(int age)
{
    m_Age = age;

    cout << "有参构造函数!" << endl;
}

//定义拷贝构造函数

Person(const Person& p)

{

m_Age = p.m_Age;

cout << "拷贝构造函数!" << endl;
}
~Person()
{
    cout << "析构函数!" << endl;
}

};

//定义返回值为Person的函数

Person func()

{

Person p(10);

return p;

}

int main()

{

func()= 10;//调用func函数,并将它的返回值作为左值
system("pause");
return 0;

}

我用的vs2019

输出结果为:

有参构造函数!

有参构造函数!

拷贝构造函数!

析构函数!

析构函数!

析构函数!

这是为什么?

还有就是返回值作为左值的问题,c++提供的默认数据类型作为返回值时
不能作为左值,用户自定义数据类型可以,有什么要求和注意事项吗?

  • 写回答

4条回答 默认 最新

  • 幸福快乐着 2020-08-25 12:46
    关注

    首先,你的程序能正常运行,你可以debug运行,将func() = 10;设断点,然后F11逐语句执行。
    系统先执行的是Person func(),声明一个Person类的对象,因为赋值10,所以系统判定为你声明的对象会调用Person::Person(int age)构造该对象,所以会先输出“有参构造函数!”。
    接下来系统会执行func()本身,其中Person p(10);又声明了一个Person类的对象,输出“有参构造函数!”
    语句return p;会将对象p拷贝输出,会调用Person(const Person& p)构造一个Person对象,输出“拷贝构造函数!同时析构对象p,输出一个“析构函数!”。
    该对象返会后,会再次被右值赋值。
    当Person func()执行完成后,剩下的两个对象都不再有存在的必要,系统则调用每个对象的析构函数,所以会输出再输出两个“析构函数!”。
    如果你想看一下析构的顺序,可以在Perseon类中增加一个变量做为不同构造函数的标志加以保存,对象析构时输出,就可以判断析构的顺序了。
    关于函数返回值做为左值的问题,本例中返回值是一个类的对象,用于函数返回的是一个引用,是可以做为左值使用的。更详细的解答,请参见(不是我写的,为了表示尊重原作者,只能给你发个链接)https://blog.csdn.net/sunshinewave/article/details/7830701?utm_source=blogxgwz9
    若有问题,再讨论。
    下面是修改后的测试代码:

    #include <iostream>
    
    using namespace std;
    
    //定义类
    
    class Person
    {
    private:
        int m_Age;
    public:
    
        //定义默认构造函数
    
        Person()
    
        {
            m_Age = 0;
            cout << "默认构造函数!" << endl;
            cout << this << endl;   // 输出该对象的指针                     
            cout << "m_Age = " << m_Age << endl << endl;
        }
    
        //定义有参构造函数
        Person(int age)
        {
    
                m_Age = age;
            cout << "有参构造函数!" << endl;
            cout << this << endl;   // 输出该对象的指针 
            cout << "m_Age = " << m_Age << endl<< endl;
    
        }
        //定义拷贝构造函数
    
        Person(const Person& p)
    
        {
    
            m_Age = p.m_Age;
            cout << "拷贝构造函数!" << endl;
            cout << this << endl;   // 输出该对象的指针 
            cout << "m_Age = " << m_Age << endl<<endl;
        }
        ~Person()
        {
            cout << this << endl;   // 输出该对象的指针 
            cout << "析构函数!" <<"   "<<m_Age<<endl;
        }
    };
    
    //定义返回值为Person的函数
    
    Person func()
    
    {
    
        Person p(10);
    
        return p;
    }
    
    
    
    
    int main()
    {
        func() = 20;//调用func函数,并将它的返回值作为左值,为了区别p(10),令func() = 20;
            system("pause");
    }
    

    运行输出:

    有参构造函数!
    00EFF898
    m_Age = 20

    有参构造函数!
    00EFF85C
    m_Age = 10

    拷贝构造函数!
    00EFF8A4
    m_Age = 10

    00EFF85C
    析构函数! 10
    00EFF8A4
    析构函数! 20
    00EFF898
    析构函数! 20
    请按任意键继续. . .

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的