C ++:重写public \ private继承

时间:2011-04-22 08:51:40

标签: c++ inheritance private public

如果B使用A继承publicB是否可以覆盖其中一个功能并强制它为私有?

class A
{
public:
    virtual double my_func1(int i);
    virtual double my_func2(int i);
}

class B : public A // Notice the public inheritance
{
public:
    virtual double my_func1(int i);
private:
    virtual double my_func2(int i);
}

反过来怎么样?如果继承类型是私有的 - 可以B强制特定的函数是公共的吗?

如果A是纯抽象怎么办?它会有所作为吗?

protected会对任何组合产生任何影响吗?

5 个答案:

答案 0 :(得分:15)

如果B使用public从A继承,B可以覆盖其中一个函数并强制它为私有吗?

尽管在my_func1()访问说明符下声明了priavte,但仍然可以通过指向class A的指针调用它,实际指向class B的对象

my_func1()的调用在运行时进行评估,具体取决于指针指向的对象类型。在编译时,编译将my_func1()调用视为对A::my_func1()的调用,并且由于A::my_func1()是公共的,编译器不会仅报告错误。只有在运行时才会评估实际的函数调用B::my_func1()

当然,你不能直接通过my_func1()的对象调用class B,因为B::my_func1()是在私有访问说明符下声明的,你不能从类外访问私有声明的成员。

反过来怎么样?如果继承类型是私有的 - B可以强制公开特定的功能吗?
NO

如果您通过Base my_func1()的指针调用class A,则在编译时它仅被评估为A::my_func1()的调用,Invalid自{{1} A`

如果A是纯抽象怎么办?它会有所作为吗?
NO
如果基类是抽象的或只是多态的,那没有区别。同样的规则将适用。

受保护会在任何组合中产生任何差异吗?
NO
正如在前两个Q中所解释的那样,如果您通过指向Base类的指针调用虚函数,则在编译时编译器仅检查Base类中该成员函数的访问权限,因为编译器将其视为对Base类成员函数的调用。对函数的实际调用在A::my_func1() is declared private in进行评估,该函数名为run timeRuntime Polymorphism,它独立于Access说明符,作为编译时构造。

总之,

覆盖基类成员不会影响访问

答案 1 :(得分:6)

差分

  

如果A是纯抽象怎么办?它会有所作为吗?

它唯一的区别是,如何使用(或不能):

A *pa = new B();
pa->my_func2(10); //calls B::my_func2() even though its private!

B *pb = new B();
pb->my_func2(10); //compilation error - trying to access private function

解释

Access-specifiers是编译时构造,因此,编译器会在编译时(显然)根据对象(或指针)的 static 类型检测到任何违反访问规则的行为。在运行时无法检测到此类违规。

所以pa->my_func2()有效,因为编译器发现pa的静态类型是A*,其中定义了公共函数my_func2(),所以表达式{{1}传递编译器的测试。因此它有效。

但是pa->my_func2()不起作用,因为pb->my_func2()的静态类型是pb,它具有私有函数B*,因此代码甚至无法编译!

答案 2 :(得分:1)

您覆盖的内容不会影响访问权限。因此,您可以创建私有继承函数的公共覆盖,就像创建公共继承函数的私有覆盖一样。

私有继承函数的公共覆盖显然必须调用实函数,它应该是内联函数,因此编译器会优化它。

答案 3 :(得分:1)

==> If B inherits from A using public, can B override one of the functions and force it to be private?

即可。指向A的指针/引用始终会将my_func2视为公开。您仍然可以使用A*A&来调用此方法。 (你在Java中提出的问题)。

==> if the inheritance type is private - can B force a specific function to be public?

如果继承类型为private / protected,则第一个位置不能将Derived类的对象分配给Base类指针/引用。例如你不能做以下!!

A* p = new B; // error

==> What if A is pure abstract? does it make a difference?

没有差异(除非您必须在B中定义方法)

==> Would protected make any difference in any combination?

没有差异(关于基类)

答案 4 :(得分:0)

我正在查看其他人发布的帖子,并发现与Derived类中的继承为private/protected时遇到的错误相关的解释有些令人困惑/不完整。

请考虑以下代码段

class A
{
public:
    virtual double my_func1(int i);
    virtual double my_func2(int i);
}

class B : private A // Notice private inheritance
{
public:
    virtual double my_func1(int i);
private:
    virtual double my_func2(int i);
}

A* ptr = new B; // this is not legal because B has a private base
ptr->my_func1(); // my_func1() is not accessible
ptr->my_func2(); // my_func2() is also not accessible not because it is private but due 
                 // base class A being inherited privately 

因此,当我们使用class B说明符从class A继承private/protected时,这意味着外界的任何人都不知道class B已从class A继承,因此它是将[{1}}类型的pointer/reference分配给class B类型的指针/引用是非法的。因此,只有在class A中继承时才能在派生类中访问私有/受保护的重写虚函数。