派生类如何访问基类属性与方法?面试代码误解解析
关于C++派生类访问基类成员的正确方式
首先得先澄清你代码里的误区:你贴的代码报错是基类指针不能直接隐式转换为派生类指针,这和派生类能不能访问基类属性完全是两回事哦!你说的“派生类无法访问基类属性”其实是不对的,只要基类成员的访问权限允许,派生类是可以直接访问的。
先看你的代码里的deriveclass,它是public继承baseclass的,基类里的a是public成员,那在派生类里直接用a就可以访问,比如修改派生类的构造函数:
class deriveclass: public baseclass { public: deriveclass() { std::cout << "derived class\n"; a = 10; // 直接访问基类的public成员a,完全没问题 std::cout << "基类的a值是:" << a << std::endl; } };
那回到面试官的问题:派生类应当通过何种方式访问基类的属性与方法?分几种情况来说:
1. 直接访问(根据继承权限)
C++的继承权限(public/protected/private)会限制派生类对基类成员的访问范围:
- 基类的**
public成员**:在public/protected继承的派生类中可以直接访问;private继承的话,基类public成员会变成派生类的private成员,派生类内部仍可访问,但外部无法访问。 - 基类的**
protected成员**:在public/protected继承的派生类中可以直接访问;private继承的话会变成派生类的private成员,仅内部可访问。 - 基类的**
private成员**:派生类无论哪种继承方式都不能直接访问,这时候需要用下面的方式。
2. 借助基类的公共/保护接口(Getter/Setter)
如果基类的成员是private的,派生类没法直接访问,这时候基类可以提供public或protected的成员函数来封装私有成员的访问,比如:
class baseclass { private: int b; // 私有成员 public: baseclass() : b(5) {} int getB() const { return b; } // 公共Getter void setB(int val) { b = val; } // 公共Setter }; class deriveclass: public baseclass { public: void modifyBaseB() { setB(20); // 通过基类的public接口修改私有成员b std::cout << "修改后基类的b值:" << getB() << std::endl; } };
3. 使用baseclass::明确指定访问基类同名成员
如果派生类有和基类同名的成员(比如同名函数或变量),直接访问会优先调用派生类自己的成员,想要访问基类的同名成员的话,需要用作用域解析符::明确指定:
class baseclass { public: void show() { std::cout << "我是基类的show函数\n"; } }; class deriveclass: public baseclass { public: void show() { std::cout << "我是派生类的show函数\n"; baseclass::show(); // 明确调用基类的show函数 } };
再补充你代码里的指针转换问题
你代码里deriveclass * bb=new baseclass();报错,是因为基类对象的内存大小通常小于等于派生类(派生类可能有自己的额外成员),把基类指针强制转成派生类指针后,后续访问派生类独有的成员会导致未定义行为,所以C++不允许这种隐式转换。如果一定要转(仅限你确定基类指针实际指向的是派生类对象的场景),可以用static_cast或者dynamic_cast(后者要求基类包含虚函数):
// 正确场景:基类指针实际指向派生类对象 baseclass* aa = new deriveclass(); deriveclass* bb = static_cast<deriveclass*>(aa); // 这是合法的,因为aa实际指向派生类实例
内容的提问来源于stack exchange,提问作者rahul_patil




