【发布时间】:2021-01-17 10:23:41
【问题描述】:
问题是我有多个专门的基类供客户用于在客户端开发派生类。多个专用基类都派生自同一个基类。所以客户端的派生类都是从同一个基类派生的,同一个基类指针可以用来指向所有的客户端类。我的问题是如何向客户隐藏基类和专用基类的私有成员和方法,并且仍然允许客户从同一个基类开发派生类?非常简化的代码如下:
在 Base.h 中。这是以下所有专用基类的单一公共基类。
class Base {
public:
Base() {}
~Base() {}
void Start();
private:
// methods to override by derived class
virtual void DoExecute() {}
private:
void Execute() {
// Do something here
DoExecute();
// Do something here
}
// Other private methods and members
}
在 Base.cpp 中
void Base::Start() {
Execute();
}
在 SpecializedBase1.h 中。一个专门的基类,供客户派生特殊客户类。
class SpecializedBase1 : public Base {
public:
SpecializedBase1();
~SpecializedBase1();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
在 SpecializedBase2.h 中。为客户派生的特殊客户类的另一个专用基类。
class SpecializedBase2 : public Base {
public:
SpecializedBase2();
~SpecializedBase2();
private:
// methods to override by derived class
virtual void DoExecute() {}
// Other private methods and members specialized for this class
}
在客户端,派生出两个类供我们调用。
class ClientClass1 : public SpecializedBase1 {
public:
ClientClass1();
~ClientClass1();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
class ClientClass2 : public SpecializedBase2 {
public:
ClientClass2();
~ClientClass2();
private:
// override base class
void DoExecute() {}
// Other private methods and members specialized for this class
}
最后
void Main() {
typedef std::shared_ptr<Base> BasePtr;
std::vector<BasePtr> vec;
// Assume client derived classes creators are available.
vec.push_back(BasePtr(new ClientClass1()));
vec.push_back(BasePtr(new ClientClass2()));
for (auto& step : vec) {
step->Start();
}
}
顺便说一句,这是非常简单的版本。请不要质疑为什么我们有多个专门的基类而不是使用同一个基类并使用 pimpl,在这一点上是不可能的。
【问题讨论】:
-
查看
protected访问说明符。这可能会解决您的问题。 -
不幸的是,protected 无法解决它 :( 我不想将文件中所有私有成员的 base.h 和 SpecializedBase1.h 和 SpecializedBase2.h 发送给客户。跨度>
-
好吧,应该被覆盖的 DoExecute 成员必须受到保护,而不是私有的。您可能希望在抽象基类不应该提供自己的实现的地方使用'=0'声明,并在所有派生类中使用'override'关键字来保护它们免受拼写错误。我认为您的问题是关于 Base::Execute 和其他私有成员,故意不打算被覆盖?
-
为什么要隐藏它们,“隐藏”是什么意思?
-
@MichaelSteffens 虚拟私有 DoExecute() 工作正常,实际上最好将虚拟函数设为私有。我不会让 DoExecute() 成为纯虚拟的,因为我希望 Base 类本身是完整的并且可以自己定义。