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

C++中友元函数修改类对象成员变量无效的问题解决

问题分析与解决方案

问题出在两个核心点:值传递导致修改无效、输入流残留换行符干扰输入。

1. 根本原因:值传递修改的是对象副本

getdata函数的参数是person x,这是按值传递——函数内部会创建原对象a的副本,你在函数里修改的只是这个副本的name和age,原对象a完全没被改动,所以printdata(a)自然还是显示默认构造的初始值。

2. 隐藏坑:输入流残留换行符

就算改成引用传递,用cin >> x.age输入年龄后,输入缓冲区里会留下一个换行符,后续如果用getline读取内容,会直接读取这个空换行,导致name被设置为空字符串,这也是需要处理的问题。


修改后的完整代码

#include <iostream>
#include <string>
#include <limits> // 处理输入流残留所需头文件
using namespace std;

class person {
    string name;
    int age;

public:
    person() {
        name = "no data found";
        age = 0;
    }

    person(string x, int y) {
        name = x;
        age = y;
    }

    friend void getdata(person&); // 声明为引用参数
    friend void printdata(person);
};

void getdata(person &x) { // 参数改为引用,直接操作原对象
    cout << "Enter name : " << endl;
    getline(cin, x.name);
    cout << "Enter age : " << endl;
    cin >> x.age;
    // 清空输入缓冲区中直到换行的所有残留字符,避免干扰后续输入
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
};

void printdata(person x) {
    cout << "Name : " << x.name << endl;
    cout << "Age : " << x.age << endl;
}

int main() {
    person a;
    getdata(a);
    person b("Raj Mishra", 17);
    printdata(a);
    printdata(b);
    return 0;
}

关键修改点

  • 将getdata的参数改为引用类型(person&):这样函数内部对x的修改会直接作用于原对象a,而不是副本。
  • 添加#include <limits>并使用cin.ignore(...):清空cin >> age后残留的换行符,确保后续getline能正常读取输入内容。

额外优化(可选):printdata函数如果只需要读取对象数据,可以改成void printdata(const person &x),避免不必要的对象拷贝,提升效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:30:44