我可以将基类的个别成员的状态更改为私有吗?

Sam*_*rsa 5 c++ inheritance wxwidgets

我正在使用wxWidgets,如果你曾经使用它,你会知道基类中有很多公共函数.我最近遇到了一种情况,我不希望SetText()直接从派生类调用方法.也就是说,派生类继承了该SetText()函数,但我不希望该函数可供客户端使用.相反,我提供了两个新函数,这些函数SetText()在执行一些额外操作之前调用但不是.

目前,客户端(我!)可以忘记调用特殊功能并简单地调用SetText().因此,将不会执行一些额外的操作.这些操作非常微妙,可能很容易被忽视.

那么,我可以将单个函数标记为私有,以便客户端无法调用它们,或者只是让客户端无法直接调用它们(它们必须使用我的函数间接调用它)?

请注意,SetText()不是虚拟的.

编辑:对于偶然发现这个问题的未来程序员,请检查标记答案和Doug T.的答案.

Nat*_*ate 4

实际上有两种方法可以做到这一点。Doug T. 对第一个问题做了很好的概述——使用私有/受保护的继承和组合——所以我不会深入讨论那个问题。

使用私有/受保护继承的问题是它掩盖了一切。然后,你必须有选择地暴露你仍然想公开的成员。如果您希望大部分内容保持公开,并且只试图掩盖一件事情,那么这可能会成为一个大问题。这就需要第二种方法——使用关键字using

例如,在您的情况下,您可以简单地声明您的类,如下所示:

class Child : public Parent
{
    //...
    private:
        using Parent::SetText; // overrides the access!
};
Run Code Online (Sandbox Code Playgroud)

只会屏蔽 SetText 方法!

但请记住,指向 a 的指针Child始终可以转换为指向 a 的指针Parent,并且可以再次访问该方法 - 但这也是继承的问题:

class Parent
{
public:
    void SomeMethod() { }
    void AnotherMethod() { }
};

class ChildUsing : public Parent
{
private:
    using Parent::SomeMethod;
};

class ChildPrivateInheritance : private Parent
{
};

void main()
{
    Parent *p = new Parent();
    ChildUsing *a = new ChildUsing();
    ChildPrivateInheritance *b = new ChildPrivateInheritance();
    p->SomeMethod();             // Works just fine
    a->SomeMethod();             //  !! Won't compile !!
    a->AnotherMethod();          // Works just fine
    ((Parent*)a)->SomeMethod();  // Compiles without a problem
    b->SomeMethod();             //  !! Won't compile !!
    b->AnotherMethod();          //  !! Won't compile !!
    ((Parent*)b)->SomeMethod();  // Again, compiles fine

    delete p; delete a; delete b;
}
Run Code Online (Sandbox Code Playgroud)

尝试访问生成SomeMethod的实例ChildUsing(在 VS2005 中):

error C2248: 'ChildUsing::SomeMethod' : cannot access private member declared in class 'ChildUsing'
Run Code Online (Sandbox Code Playgroud)

但是,尝试访问 或SomeMethod AnotherMethod实例会ChildPrivateInheritance产生:

error C2247: 'Parent::SomeMethod' not accessible because 'ChildPrivateInheritance' uses 'private' to inherit from 'Parent'
Run Code Online (Sandbox Code Playgroud)