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
相关产品推荐
相关产品推荐

