C++访问嵌套类属性出现访问违例?原因分析与解决方法
问题分析与解决
错误根源
你遇到的访问违例,核心问题出在Job类构造函数的自赋值错误,以及错误使用char*存储字符串:
- Job构造函数中,参数名
name和成员变量名name重名,导致name = name;只是把参数赋值给自己,成员变量name完全没被初始化,依然是初始的空指针(而且char* name = ""本身就有问题,字符串字面量是const char*,强转成char*属于未定义行为)。 - Player构造函数初始化
job(job_name)时,调用的是有问题的Job构造函数,最终player1.job.name是空指针,cout输出空指针就会触发访问违例。
正确解决方式
方式1:改用std::string(推荐)
直接用C++标准库的std::string存储字符串,避免指针管理的麻烦,同时修正构造函数的变量名冲突:
Foo.h
#include <iostream> #include <string> #include <vector> class Job { public: std::string name; Job() = default; // 参数名区分成员变量,用std::string避免指针问题 Job(const std::string& job_name) : name(job_name) {} }; class Player { public: std::string name; std::string id; std::string job_name; Job job; Player() = default; Player(const std::string& player_name, const std::string& job_name) : name(player_name), job_name(job_name), job(job_name) {} };
Foo.cpp
#include <iostream> #include "Foo.h" int main() { Player player1("player1", "default"); std::cout << player1.job.name << std::endl; }
方式2:坚持用char*(不推荐)
需要修正构造函数的变量名冲突,同时匹配字符串字面量的const属性:
Foo.h
#include <iostream> #include <string> #include <vector> class Job { public: const char* name = ""; // 改成const char*,匹配字符串字面量类型 Job() = default; // 参数名改为param_name,区分成员变量 Job(const char* param_name) : name(param_name) {} }; class Player { public: const char* name = ""; const char* id = ""; const char* job_name = ""; Job job; Player() = default; Player(const char* player_name, const char* job_name) : name(player_name), job_name(job_name), job(job_name) {} };
关于getter的问题
- 你当前场景不需要getter,
job.name是public属性,直接访问完全合法,错误不是因为访问权限,而是指针未正确初始化。 - 只有当需要封装属性(比如控制读写权限、添加逻辑校验)时,才需要写getter,不需要为每个属性都编写。
- 嵌套属性的getter设计很简单,比如给Job类添加:
const std::string& getName() const { return name; },之后访问时用player1.job.getName()即可。
为什么player1.name能正常输出?
Player构造函数初始化列表里的name(name),语法上是直接指定成员变量赋值,虽然参数名和成员名重名,但初始化列表的规则会优先识别成员变量,所以这里正确完成了赋值,player1.name指向了字符串字面量的有效地址,因此能正常输出。
内容的提问来源于stack exchange,提问作者linx
相关产品推荐
相关产品推荐

