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

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条)

报告相同问题?

悬赏问题

  • ¥15 idea自动补全键位冲突
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 定制ai直播实时换脸软件
  • ¥100 栈回溯相关,模块加载后KiExceptionDispatch无法正常回溯了
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页