1. 问题背景与场景还原
最近在开发一个数据库连接池项目时,我遇到了一个典型的C++继承问题。当时我需要自定义一套异常处理机制,于是设计了一个基础异常类Exception,并派生出各种特定场景的异常子类。在实现过程中,我发现子类无法直接访问父类的private成员,这让我对C++的继承机制产生了新的认识。
让我们先还原这个场景。我定义了一个基础异常类Exception,它包含两个private成员变量:
cpp复制class Exception {
public:
Exception(const string& errmsg, int id)
:_errmsg(errmsg), _id(id) {}
private:
string _errmsg; // 错误信息
int _id; // 错误代码
};
然后我创建了一个派生类SqlException来处理数据库异常:
cpp复制class SqlException : public Exception {
public:
SqlException(const string& errmsg, int id, const string& sql)
:Exception(errmsg, id), _sql(sql) {}
virtual string what() const {
string str = "SqlException:";
str += _errmsg; // 这里编译报错
str += "->";
str += _sql;
return str;
}
private:
const string _sql;
};
当我尝试在SqlException的what()方法中直接访问父类的_errmsg成员时,编译器报错:"'_errmsg' is a private member of Exception"。这让我很困惑——既然子类继承了父类,为什么不能访问父类的私有成员?
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. C++继承机制深度解析
2.1 访问权限的本质
C++中的访问控制(public、protected、private)实际上是类与外部世界之间的契约,而不是简单的"可见性"概念。private成员是类的内部实现细节,对外完全隐藏,包括对其派生类也是如此。这种设计是面向对象编程中封装性原则的核心体现。
在C++标准中明确规定(ISO/IEC 14882:2020 §11.8):
- private成员只能被声明它的类的成员函数和友元访问
- protected成员可以被派生类访问
- public成员可以被任何代码访问
2.2 继承方式的影响
C++支持三种继承方式:public、protected和private继承。不同的继承方式会影响基类成员在派生类中的访问权限:
| 基类成员权限 | public继承后 | protected继承后 | private继承后 |
|--------------|-------
