c++ - 通过公共(public)继承仅公开某些方法

标签 c++ class c++11 inheritance polymorphism

我有一个基类,比如 Employee,上面有一些方法。稍后我将派生一些子类,如 ManagerDeveloperDesigner 等,它们也是雇员(因为继承)。现在说代码看起来像 -

#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 已经分配了他们的部门,所以我不希望他们访问此功能。

我尝试了一种非常 hacky 的方法来解决这个问题,通过编写另一层类 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();
}

虽然看起来很聪明,但它不起作用 -

prog.cc: In function 'int main()':
prog.cc:27:23: error: 'Employee' is an inaccessible base of 'Designer'
     Employee *E = new Designer;

那么我在这里有哪些选择?一种愚蠢的方法是将该函数设置为 virtual ,但子类又不会被迫覆盖它,如果他们忘记声明它,它会调用父类的函数?

最佳答案

But now what I want to do is, hide one of the public class member from child class invocation, so that child class isn't able to call it but base class object can.

继承基于Liskov substitution principle .简而言之,在我使用 Base* 的任何地方,我都应该能够使用 Derived* 并且一切都应该等效地工作。您希望通过使派生类的基类操作格式错误来违反该概念。那意味着你的抽象是错误的。

而且,这样的事情无论如何也没有意义。你不能动态地实现这样的机制,如果你静态地实现它,那么:

Derived d;
Base* b = &d;

b->foo(); // OK
d.foo();  // error

我总是可以这样做:

static_cast<Base&>(d).foo(); // OK, just verbose

您可能需要层次结构的第二个分支:

struct Base { };
struct SpecialDerived : Base { void foo(); };
struct NormalDerived : Base { };

现在只有 SpecialDerived 可以调用 foo(),但是每个 SpecialDerived 仍然是一个 Base 并且每个 code>NormalDerived 是一个 Base,一切都运行得很顺利。

关于c++ - 通过公共(public)继承仅公开某些方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39542917/

相关文章:

c++ - 在这种情况下,Win32 错误代码 122 是否有点良性?

c++ - 访问主运行循环时应​​用程序崩溃 (SIGABRT)?

c# - 故障排除 : does not contain a static 'main' method suitable for an entry point

c++ - 读取文件和未定义的行为

c++ - Direct2D 深度缓冲区

c++ - OpenCV C++ 在彩色图像中组合灰色图像

c++ - 构造函数调用问题

c++ - 即使在 RVO 禁用时定义了 move 构造函数,也会发生对象复制

c++ - 初始化器究竟是什么时候被临时销毁的?

java - Java 中私有(private)静态嵌套类中的访问修饰符