C++ 关于构造函数的返回值

结论:构造函数确实隐式地返回了一个该类的对象。

或许底层原理并非如此,但对于接触底层不多的用户来说,这样去理解,我想是没什么大问题的。

        最近在学习C++类与对象时,看到了“构造函数不返回任何东西”的说法。然而学到异常处理的部分,却又看到了“throw classname();”这样的语句,这让我非常纳闷。按理说,throw一个函数,应该等价于throw这个函数返回值。但是构造函数classname()不是没有返回值吗?那这里到底throw了个啥?

        在好奇心的驱使下,我百度了一圈,发现普遍共识还是构造函数不返回任何东西。然而鉴于“classname obj=classname();”和“throw classname();”这样的写法确实能通过编译,我这个没接触过底层的人还是更愿意相信,构造函数是返回了某些东西的,尽管官方没有承认。

        那么它到底返回了什么内容呢?是一个对象吗?还是一个对象的引用?我决定自己动手测一测。(看到个别说法是返回this指针,这是不可能的。如果返回this指针,那么“classname obj=classname();”这样的语句就无法通过编译,因为不能把指针转换为对象)

上测试代码:

#include <iostream>
using namespace std;

class A {
public:
    //这是构造函数
    A(void) {
        cout<<"An A object is created.\n"<<endl;
        i=12;
    }

    const char *thrown(void) {
        return "An A is thrown.\n";
    }

    int i;
} ;

//作为对比,这是一个确定返回对象的函数
A obj(void) {
    A obj;
    return obj;
}

//作为对比,这是一个确定返回对象引用的函数
A &quo(void) {
    static A obj;
    return obj;
}

int main(void) {
    //cout<<++A().i<<endl;
    //cout<<++obj().i<<endl;
    //上面两行编译时均会报错:将临时量作为左值
    cout<<++quo().i<<endl;//只有返回对象引用的函数可在调用的同时操作成员

    //这说明构造函数没有返回对象的引用

    try {
        //下面两行中保留任意一行,均会执行catch(A obj),说明构造函数确实返回了一个对象
        //throw obj();
        throw A();

    } catch(A obj) {
        cout<<obj.thrown()<<endl;
    }

    //然而构造函数和返回对象的函数,sizeof值却不同
    //cout<<sizeof(obj())<<endl;
    //cout<<sizeof(A())<<endl;
    /*后来发现取sizeof没有任何意义,因为sizeof的过程中根本没有调用函数,
    其测得的并不是实际返回值所占空间*/

    return 0;
}

测试思路很简单:

1.如果构造函数返回对象的引用,那么应当可以在调用构造函数的同时,将其成员作为左值进行操作,因为C++只允许函数返回静态或全局量的引用,这导致可以在调用这种函数的同时,将其作为左值。

2.如果构造函数返回一个对象,那么throw一个构造函数,和throw一个确定返回对象的自定义函数,catch的结果应该是一样的。

3.如果构造函数真的返回一个对象,那么对构造函数取sizeof,和对一个确定返回对象的自定义函数取sizeof,结果应该是一样的。注:此步作废。原因:一开始对sizeof的原理不了解,以为sizeof一个函数时,会调用这个函数,然后测量其返回内容所占的空间。后来注意到,取sizeof这一步中,程序没有输出“An A object is created.”这行内容,说明在sizeof的过程中,传入的函数根本被没有被调用,也就不可能执行任何return。百度到的内容也确实印证了这一点,即对于一个函数,sizeof不会调用函数本身,而是直接检查函数声明。这样一来,这一步就失去了意义,因为sizeof所测的并不是函数实际返回的内容。


测试结果:

1.不能将构造函数(的成员)作为左值,说明其没有返回对象引用。

2.throw一个构造函数,确实可以catch到一个对象,甚至可以调用其成员函数,这说明构造函数返回了一个对象。

3.对构造函数和确定返回对象的自定义函数分别取sizeof,前者结果为1,后者结果为4,不一致,说明构造函数返回的不是对象,2不成立。注:作废,理由同上。(顺带一提,sizeof(void)就是1。估计构造函数在底层确实近似于void型,因此被指为“不返回任何东西”)

        至此,得出结论:构造函数确实隐式地返回了一个该类的对象。或许底层原理并非如此,但对于接触底层不多的用户来说,这样去理解,我想是没什么大问题的。

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值