我有一个基类,说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 dept\n";
allDept(); }
virtual ~Employee() {}
};
class Manager: public Employee{
private : char dept[5] = "aaaa";
public: void showOwnDept(){std::cout<< "Manager can see own dept\n";}
};
class Designer: public Employee{
private : char color = 'r';
public: void showOwnDept(){std::cout<< "Designer can see own dept\n";}
};
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();
}
因此,我们在这里可以看到,我可以强制转换并使用多态性,将基类指针指向派生类对象,并仍然在子类上调用基类可访问方法。同样要从子类中调用子类方法,我可以动态地将其回退。
但是现在我要做的是,从子类调用中隐藏一个公共(public)类成员,以便子类无法调用它,而基类对象可以调用它。以
showEveryDept()
为例,它可以由子类和父类调用。但是,由于已经为Designer和Manager分配了他们的部门,因此我不希望他们使用此功能。我尝试了一种非常拙劣的方式来解决此问题,方法是编写另一层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 dept\n";
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 dept\n";}
};
class Designer: public ELayer{
private : char color = 'r';
public: void showOwnDept(){std::cout<< "Designer can see own dept\n";}
};
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();
}
但看起来很聪明,却行不通-
那么我在这里有什么选择?一种愚蠢的方法是使该函数成为虚函数,但子类也不会被强制重写它,并且如果他们忘记声明它,它将调用父函数吗?
最佳答案
另一个选择是在子级中使用using
声明以及私有(private)继承来有选择地决定您可以从中访问什么。这比virtual
替代方法更加灵活,并且没有任何额外的开销。另外,例如,它可以将公共(public)访问“转换”为 protected 访问。
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 dept\n";
allDept();
}
virtual ~Employee() {}
};
class Designer : private Employee
{
private:
char color = 'r';
public:
using Employee::tellName();
void showOwnDept()
{
std::cout<< "Designer can see own dept\n";
}
};
现在,您可以调用
Desginer::tellName()
和Designer::showOwnDept()
,但是Designer::showEveryDept()
是私有(private)的!但是,缺点是您可能不再将Designer*
从外部代码转换为Employee*
。您可以在Employee
中添加一个方法来做到这一点。但是,您应该记住在派生类中执行using Employee::as_employee
。class Employee
{
public:
Employee& as_employee()
{
return *this;
}
const Employee& as_employee() const
{
return *this;
}
};
无论如何,您应该问自己这是否真的是最理想的设计,并且确实需要这样做,或者在
showDept()
中仅具有一个(可选的)虚拟函数Employee
来使派生类可以(或者必须这样做)会更好吗?纯)覆盖。编辑:从我在另一个答案中读到的您的评论中,我可以轻松得出结论,您的问题是您不了解基类
Employee
不能用作某种“未分配的员工”占位符。这么说:设计师是雇员,未分配的雇员是雇员,但是设计师不是未分配的雇员。因此,最好是重组代码。无论如何,为了完整起见,我将保留上述解决方案。关于c++ - 通过公共(public)继承仅公开某些方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39542917/