C++中基类作函数参数时如何访问传入派生类的独有属性
问题核心原因
- 对象切片:
Print(A c)采用值传递,传入派生类B对象时,只会拷贝B中属于基类A的成员,B特有的成员会被截断,函数内拿到的c永远是基类A的实例,不可能访问派生类独有成员。 - 静态类型检查失败:编译阶段c的类型被识别为A,A不存在y成员,编译器直接报错,和运行时实际传入的参数类型无关。
- 同名成员隐藏:你在派生类B中重新定义了
isB成员,属于隐藏基类的同名成员,基类子对象的isB仍为默认值false,就算没有切片,用基类引用/指针访问isB拿到的也是基类的false,判断逻辑无法生效。
解决方案
方案1:手动类型标记+向下转型
修改派生类构造逻辑修改继承来的isB标记,形参改用引用/指针避免对象切片,确认类型后向下转型访问派生类成员:
#include <iostream> using namespace std; class A{ public: bool isB = false; int x = 69; }; class B : public A{ public: B() { // 直接修改继承自基类的isB,不重新定义同名成员 isB = true; } int y = 420; }; // 引用传递避免对象切片 void Print(A& c){ if (c.isB) { // 向下转型为B类型引用后访问y cout << static_cast<B&>(c).y << endl; } else { cout << c.x << endl; } } int main() { A a; B b; Print(a); // 输出69 Print(b); // 输出420 return 0; }
方案2:动态类型判断(更安全)
基类添加虚函数,用dynamic_cast自动判断运行时类型,不需要手动维护类型标记,避免标记写错的风险:
#include <iostream> using namespace std; class A{ public: int x = 69; // 基类至少有一个虚函数才能使用dynamic_cast,虚析构是常规写法 virtual ~A() = default; }; class B : public A{ public: int y = 420; }; void Print(A& c){ // 尝试转型为B的指针,转型成功说明运行时实际类型为B if (B* b_ptr = dynamic_cast<B*>(&c)) { cout << b_ptr->y << endl; } else { cout << c.x << endl; } } int main() { A a; B b; Print(a); // 输出69 Print(b); // 输出420 return 0; }
方案3:多态实现(最优,符合面向对象设计)
把打印逻辑定义为虚函数,由派生类自行实现对应逻辑,不需要手动转型,新增派生类也不需要修改外层Print函数的代码:
#include <iostream> using namespace std; class A{ public: int x = 69; virtual void Print() { cout << x << endl; } virtual ~A() = default; }; class B : public A{ public: int y = 420; void Print() override { cout << y << endl; } }; void Print(A& c){ c.Print(); } int main() { A a; B b; Print(a); // 输出69 Print(b); // 输出420 return 0; }
内容的提问来源于stack exchange,提问作者MrCheese
相关产品推荐
相关产品推荐

