You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++类成员函数返回类对象:读变量正常,赋值变量失效

问题分析:返回值、引用、指针的行为差异

我编写了如下C++代码,发现调用ParentClass的getSubsidiaryClass()返回的对象调用putLittleDouble()无法修改成员变量,但读取变量正常;而调用返回引用的getSubsidiaryClassReference()和返回指针的getSubsidiaryClassPointer()则可正常修改。已排除访问权限问题,想了解为何第一种方法失效,后两种可行?

#include <iostream>

class SubsidiaryClass {

    private:
        double                 little_double;

    public:
        double                 getLittleDouble()                                      {return little_double;}
        void                   putLittleDouble(double input)                          {little_double = input; return;}
};

class ParentClass {

    private:
        double                 little_double;
        SubsidiaryClass        subsidiary_class;
 
    public:
        double                 getLittleDouble()                                      {return little_double;}
        void                   putLittleDouble(double input)                          {little_double = input; return;}

        SubsidiaryClass        getSubsidiaryClass()                                   {return subsidiary_class;}
        SubsidiaryClass&       getSubsidiaryClassReference()                          {return subsidiary_class;}
        SubsidiaryClass*       getSubsidiaryClassPointer()                            {return &subsidiary_class;}

};

int main() {

    ParentClass parent_class;
  
    parent_class.getSubsidiaryClass().putLittleDouble(1.1);                                    // does not work, no error message 
    std::cout << parent_class.getSubsidiaryClass().getLittleDouble() << std::endl;

    parent_class.getSubsidiaryClassReference().putLittleDouble(2.2);                          // works fine
    std::cout << parent_class.getSubsidiaryClassReference().getLittleDouble() << std::endl;
    std::cout << parent_class.getSubsidiaryClass().getLittleDouble() << std::endl;

    parent_class.getSubsidiaryClassPointer() -> putLittleDouble(3.3);    // works fine
    std::cout << parent_class.getSubsidiaryClassPointer() -> getLittleDouble() << std::endl;    // works fine
    std::cout << parent_class.getSubsidiaryClass().getLittleDouble() << std::endl;

    return 0;

}

核心原因:返回值类型决定操作的是原对象还是副本

1. getSubsidiaryClass() 返回值的问题

这个函数的返回类型是SubsidiaryClass(值类型),调用它时会复制一份ParentClass内部的subsidiary_class对象,返回的是这个临时副本。你调用putLittleDouble(1.1)修改的是这个临时副本的成员变量,执行完这行代码后,这个临时副本就会被销毁,ParentClass里的原对象完全没被改动。

而后续读取时,getSubsidiaryClass()又会生成一个新的副本,读取的是新副本的默认值(double类型默认初始化是0),所以看起来好像读取正常但修改无效。

2. getSubsidiaryClassReference() 返回引用的作用

返回类型SubsidiaryClass&是引用类型,引用可以理解为原对象的“别名”,返回的引用直接指向ParentClass内部的subsidiary_class对象。调用putLittleDouble(2.2)时,操作的就是原对象本身,修改自然会生效,后续不管是通过引用还是再次调用值返回的函数(此时新副本会复制原对象的修改后的值),都能读到正确的结果。

3. getSubsidiaryClassPointer() 返回指针的作用

返回类型SubsidiaryClass*是指针,指针存储的是ParentClass内部subsidiary_class对象的内存地址。通过指针->调用函数时,直接访问的是该地址对应的原对象内存,所以修改操作直接作用在原对象上,效果和返回引用一致。

内容的提问来源于stack exchange,提问作者user26521688

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:57:05