c – 仅通过公共继承暴露某些方法
我有一个基类,说Employee有一些方法.我稍后会派出一些子类,如Manager,Developer,Designer等,这些子类也是员工(因为继承).现在说代码看起来像 –
#include <iostream> #include <vector> class Employee{ private : char name[5] = "abcd"; void allDept(){ std::cout<<"Woo"; } public: void tellName(){std::cout << name << "n"; } void showEveryDept(){std::cout<< "Employee can see every deptn"; allDept(); } virtual ~Employee() {} }; class Manager: public Employee{ private : char dept[5] = "aaaa"; public: void showOwnDept(){std::cout<< "Manager can see own deptn";} }; class Designer: public Employee{ private : char color = 'r'; public: void showOwnDept(){std::cout<< "Designer can see own deptn";} }; int main(){ Employee *E = new Designer; E->showEveryDept(); // E->showOwnDept(); // will not work,but can be casted dynamically and even statically if sure,to call it! Designer* D = dynamic_cast<Designer*>(E); D->showOwnDept(); } 所以我们在这里看到的是我可以使用多态,将基类指针指向派生类对象,并仍在子类上调用基类可访问方法.另外,要从子类调用子类方法,我可以动态地将其转换回来. 但是现在我想要做的是,从子类调用中隐藏一个公共类成员,这样子类不能调用它,但是基类对象可以.以showEveryDept()为例,它可以由子类和父类调用.但是由于Designer和Manager已经分配了他们的部门,我不希望他们访问这个功能. 我尝试了一种非常hacky的方法来解决这个问题,通过编写另一层类的b / w Employee类和它的孩子,就像这样 – class Employee{ private : char name[5] = "abcd"; void allDept(){ std::cout<<"Woo"; } public: void tellName(){std::cout << name << "n"; } void showEveryDept(){std::cout<< "Employee can see every deptn"; allDept();} virtual ~Employee() {} }; class ELayer: private Employee{ private: using Employee::showEveryDept; private: using Employee::tellName; }; class Manager: public ELayer{ private : char dept[5] = "aaaa"; public: void showOwnDept(){std::cout<< "Manager can see own deptn";} }; class Designer: public ELayer{ private : char color = 'r'; public: void showOwnDept(){std::cout<< "Designer can see own deptn";} }; int main(){ Employee *E = new Designer; E->showEveryDept(); // E->showOwnDept(); // will not work,but can be casted dynamically // and even statically if sure,to call it! Designer* D = dynamic_cast<Designer*>(E); D->showOwnDept(); } 但是看起来很聪明,它不起作用 –
那么我的选择是什么?一种愚蠢的方法是将该函数设置为虚拟,但是子类不会被强制覆盖它,如果它们忘了声明它,它会调用父函数吗? 解决方法
另一个选择是使用子进程中的声明以及私有继承来有选择地决定从中可以访问的内容.这比虚拟替代方案更灵活,并且没有任何额外开销.此外,它可以将公共访问“转换”为受保护的访问.
class Employee { private: char name[5] = "abcd"; void allDept() { std::cout << "Woo"; } public: void tellName() { std::cout << name << "n"; } void showEveryDept() { std::cout << "Employee can see every deptn"; allDept(); } virtual ~Employee() {} }; class Designer : private Employee { private: char color = 'r'; public: using Employee::tellName(); void showOwnDept() { std::cout<< "Designer can see own deptn"; } }; 现在,您可以调用Desginer :: tellName()和Designer :: showOwnDept(),但Designer :: showEveryDept()是私有的!但是,缺点是您不能再从外部代码将Designer *转换为Employee *.您可以在Employee中添加一个方法来做到这一点.但是,您应该记得在派生类中使用Employee :: as_employee. class Employee { public: Employee& as_employee() { return *this; } const Employee& as_employee() const { return *this; } }; 无论如何,你应该问自己这是否真的是最好的预期设计,你真的需要这样做,或者如果在Employee中有一个(可选纯的)虚拟函数showDept()更好,派生类可能(或必须),如果纯粹的覆盖. 编辑:从你的评论我读到另一个答案,我可以很容易地得出结论,你的问题是你不明白基类,员工不会被用作某种“未分配的员工”占位符.这样:设计师是员工,未分配的员工是员工,但设计师不是未分配的员工.因此,最好重新构建代码.无论如何,为了完整起见,我将离开上述解决方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |