【问题标题】:Hide private methods and members in c++在 C++ 中隐藏私有方法和成员
【发布时间】: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 类本身是完整的并且可以自己定义。

标签: c++ private


【解决方案1】:

部分解决方案:如果

  • 你只需要隐藏的私有函数(没有成员变量)
  • 并且可以将这些功能需要访问的所有可见成员设为公共

然后您可以在类之外提供这些隐藏的“成员”作为非成员,并带有指向该对象的显式指针。这些功能可以在相应的 *.cpp 文件中实现,而无需在声明中提及,使用静态内部链接或匿名命名空间,并且对客户端完全不可见。

一旦您还有要隐藏的私人数据,这个想法就会中断。原因是堆栈上的对象分配。在这种情况下,客户有责任提供所需的内存,因此需要知道对象的内存布局,包括所有私有成员。不可能,如果你隐藏它们。为此,您需要在构造函数中进行堆分配,这归结为 PIMPL。

【讨论】:

  • 感谢您的回复。我确实有私人成员要隐藏。我一直在考虑使用 PIMPL,但是,这会破坏从单个公共基类派生的客户端派生类。
猜你喜欢
  • 2010-09-17
  • 2013-07-07
  • 2021-01-16
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 2011-12-11
  • 1970-01-01
相关资源
最近更新 更多