核心内容摘要
144447大但人文艺术:光影叙事,定格永恒之美
文章目录
前景提要
场景还原
问题根源
修复方案标题方案1将父类成员改为 protected方案2在父类中提供 get 方法
总结
前景提要最近在写一个自定义异常类的代码时我遇到了一个经典的C继承问题。
当时我觉得既然子类继承了父类就应该像访问自己的私有成员一样直接访问父类的private成员结果编译器直接报错了。
今天就来复盘一下这个踩坑过程顺便把C继承的访问权限规则彻底理清楚。
提示以下是本篇文章正文内容下面案例可供参考
场景还原我写了一个父类Exception它包含两个private成员_errmsg错误信息和_id错误码。
然后我又写了一个子类SqlException继承用它用来处理SQL相关的异常。
在子类的what成员函数中我想把父类的_errmsg拼接到自己的错误信息里于是写了这样的代码classException//基类{public:Exception(conststringerrmsg,intid):_errmsg(errmsg),_id(id){}private:string _errmsg;int_id;};//classSqlException:publicException{public:SqlException(conststringerrmsg,intid,conststringsql):Exception(errmsg,id),_sql(sql){}virtualstringwhat()const{string strSqlException;str_errmsg;str-;str_sql;returnstr;}private:conststring _sql;};结果编译器直接给我报了一个错_errmsgis aprivatemember of Exception我当时就懵了我不是已经继承了父类了吗为什么不能直接使用它的私有成员
问题根源后来我才明白C的继承并不是把父类的所有成员都“复制”给子类而是有严格的访问权限控制父类成员权限 子类继承后访问权限public继承父类成员权限子类继承后访问权限public继承public保持public外部和子类都能访问protected保持protected 只有子类能访问private子类完全无法直接访问只能通过父类的 public / protected 接口间接访问简单来说父类的 private 成员是父类的“私有财产”即使是它的子类也无权直接触碰。
这个设计是为了保证封装性让父类可以自由修改自己的内部实现而不影响子类。
修复方案想通了原理之后我就找到了两种可行的修复方法标题方案1将父类成员改为 protected这是最简单直接的方式把父类的 _errmsg 和 _id 从 private 改成 protected这样子类就可以直接访问了classException//基类{public:Exception(conststringerrmsg,intid):_errmsg(errmsg),_id(id){}protected://privatestring _errmsg;int_id;};方案2在父类中提供 get 方法如果不想破坏父类的封装性可以在父类里提供 public 的访问接口让子类通过这些方法间接获取私有成员classException{private:string _errmsg;int_id;public:stringgetErrMsg()const{return_errmsg;}intgetId()const{return_id;}// ...};然后在子类这样调用virtualstringwhat()const{returnSqlException: getErrMsg();}
总结这次踩坑让我深刻理解了继承不等于拥有父类的私有成员。
C的访问权限规则不是为了故意刁难开发者而是为了让代码更健壮、更易于维护。
遵守这些规则能让我们写出更符合面向对象设计思想的代码。
如果你也遇到了类似的问题希望这篇文章能帮你少走弯路。