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

C++访问嵌套类属性出现访问违例?原因分析与解决方法

问题分析与解决

错误根源

你遇到的访问违例,核心问题出在Job类构造函数的自赋值错误,以及错误使用char*存储字符串:

  1. Job构造函数中,参数名name和成员变量名name重名,导致name = name;只是把参数赋值给自己,成员变量name完全没被初始化,依然是初始的空指针(而且char* name = ""本身就有问题,字符串字面量是const char*,强转成char*属于未定义行为)。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:06:14