【问题标题】:Can I exclude a base class member from the derived class?我可以从派生类中排除基类成员吗?
【发布时间】:2012-10-29 18:08:21
【问题描述】:

假设我有一个名为CWindow的课程:

class CWindow
{
public:
    virtual bool Create();
};

在派生类CMyWindow中,我想将Create(void)方法重载为Create(int someParam),但是,我不希望用户能够调用Create(void)方法,只能调用Create(int someParam)。这可能吗?可以吗:

class CMyWindow : public CWindow
{
private:
    bool Create();
public:
    virtual bool Create(int someParam);
};

这有效吗?它基本上会让CWindow的以前的公共成员成为CMyWindow的私人成员吗?

我想如果可以从一个类中“排除”一个成员,这是最接近这样做的,因为 AFAIK 在 C++ 中没有神奇的 youcantbeamember 关键字

我最好的猜测是不,你不能这样做。但我只是希望,因为我想避免创建一个包含除 Create() 成员之外的所有内容的基类,并从 CWindowBase 派生 CWindowCMyWindow

【问题讨论】:

  • 这是完全有效的代码,应该可以正常工作。
  • static_cast<CWindow*>(ptrToCMyWindow)->Create(); 将永远是可能的

标签: c++ oop inheritance polymorphism virtual


【解决方案1】:

可以真正做到这一点,它会按预期工作。唯一的问题是CMyWindow 仍然是CWindow,这允许Create()

CMyWindow w;
w.Create(); // does not compile
static_cast<CWindow>(w).Create(); // compiles just fine

如果您不想不惜一切代价允许这样做,那么您必须将CWindow::Create 抽象化,并可能将当前实现(如果有)作为派生类可以显式调用的protected 成员提供:

class CWindow
{
public:
    virtual bool Create() = 0;
protected:
    bool DefaultCreateImplementation();
};

class CNormalWindow : public CWindow
{
public:
    bool Create() { return DefaultCreateImplementation(); }
}

class CMyWindow : public CWindow
{
private:
    virtual bool Create(); // declared but not defined
                           // if called by accident will produce linker error
public:
    virtual bool Create(int someParam);
};

【讨论】:

  • 嗯,我在 CMyWindow::Create(void) 上得到链接器错误,而没有调用任何 Create 方法 (vc2012)。
【解决方案2】:

您似乎从 CWindow 公开继承来继承其实现。使用公共继承时,这不应该是您的意图。公共继承意味着接口的继承。但是你不想继承CWindows接口,你想隐藏它!

想想这样的替代设计

class Window
{
public:
    // EVERY Window can create the window using this method
    virtual bool Create();  
};


class MyWindow : public Window
{
public:
    // Initialize MyWindow with an additional parameter, 
    // that is used to create the window
    MyWindow(int param);

    // Create the window using the parameter
    virtual bool Create() override;
private:
    int param;
};

class View
{
public:
    void AddWindow(Window& window)
    {
        myWindows.Add(&window);
        window.Create();  // I can call this on EVERY Window instance
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2023-03-11
    • 2021-11-15
    • 2011-11-10
    • 2020-12-24
    • 2014-04-30
    相关资源
    最近更新 更多