1、如何从派生类对象调用派生类覆盖的基类方法?

class Base{
 public:
 void foo(){cout<<“base”;}
 };
 class Derived:public Base{
 public:
 void foo(){cout<<“derived”;}
 }
 int main(){
 Derived bar;
 //call Base::foo() from bar here?
 return 0;
 }2、您可以使用qualified-id来始终(*)引用基类的函数:
 #include 
 class Base{
 public:
 void foo(){std::cout<<“base”;}
 };
 class Derived : public Base
 {
 public:
 void foo(){std::cout<<“derived”;}
 };
 int main()
 {
 Derived bar;
 //call Base::foo() from bar here?
 bar.Base::foo(); // using a qualified-id
 return 0;
 }

3、()访问限制仍然适用,基类可能是模糊的。如果Base :: foo不是虚拟的,那么Derived :: foo不会覆盖Base :: foo。相反,Derived :: foo隐藏了Base :: foo。以下示例可以看出差异:

struct Base {
 void foo() { std::cout << “Base::foo\n”; }
 virtual void bar() { std::cout << “Base::bar\n”; }
 };
 struct Derived : Base {
 void foo() { std::cout << “Derived::foo\n”; }
 virtual void bar() { std::cout << “Derived::bar\n”; }
 };
 int main() {
 Derived d;
 Base b = &d;
 b->foo(); // calls Base::foo
 b->bar(); // calls Derived::bar
 }


(Derived :: bar是隐式虚拟的,即使你不使用virtual关键字,只要它的签名与Base :: bar兼容)。
一个qualified-id是X :: Y或者:: Y的形式。在::之前的部分指定了我们要查找标识符Y的位置。在第一种形式中,我们查找X,然后我们查找Y来自X的上下文。在第二种形式中,我们在全局命名空间中查找Y。
unqualified-id不包含一个::,因此(本身)不指定查找名称的上下文。在表达式b→foo中,b和foo都是不合格的。 b在当前上下文中查找(在上面的示例中是主要功能)。我们找到局部变量Base * b。因为b-> foo具有类成员访问的形式,所以我们从b类型(或* b)的上下文中查找foo。所以我们从Base的上下文中查找foo。我们将在Base中找到成员函数void foo(),我将引用为Base :: foo。对于foo,我们现在完成了,并调用Base :: foo。对于b-> bar,我们首先找到Base :: bar,但它被声明为虚拟。因为它是虚拟的,我们执行一个虚拟调度。这将调用对象b类型的类层次结构中的final函数覆盖。因为b指向Derived类型的对象,所以最终的覆盖者是Derived :: bar。从Derived的上下文中查找名称foo时,我们会发现Derived :: foo。这就是为什么Derived :: foo被隐藏为Base :: foo。在Derived的成员函数中使用简单的foo()或this-> foo()的表达式将从Derived的上下文中查找。当使用qualified-id时,我们明确指出在哪里查找名称的上下文。 Base :: foo表示我们要从Base的上下文中查找名字foo(例如,可以找到Base继承的函数)。另外,它禁用虚拟调度。
因此,d.Base :: foo()将找到Base :: foo并调用它; d.Base :: bar()将找到Base :: bar并调用它。

4、纯虚拟功能可以实现。它们不能通过虚拟调度进行调用,因为它们需要被覆盖。但是,您仍然可以通过使用qualified-id来调用它们的实现(如果有的话)。

#include 
 struct Base {
 virtual void foo() = 0;
 };
 void Base::foo() { std::cout << “look ma, I’m pure virtual!\n”; }struct Derived : Base {
 virtual void foo() { std::cout << “Derived::foo\n”; }
 };
 int main() {
 Derived d;
 d.foo(); // calls Derived::foo
 d.Base::foo(); // calls Base::foo
 }
 类成员和基类的访问说明符对于是否可以使用限定id来对派生类型的对象调用基类的函数有影响。
 #include 
 struct Base {
 public:
 void public_fun() { std::cout << “Base::public_fun\n”; }
 private:
 void private_fun() { std::cout << “Base::private_fun\n”; }
 };
 struct Public_derived : public Base {
 public:
 void public_fun() { std::cout << “Public_derived::public_fun\n”; }
 void private_fun() { std::cout << “Public_derived::private_fun\n”; }
 };
 struct Private_derived : private Base {
 public:
 void public_fun() { std::cout << “Private_derived::public_fun\n”; }
 void private_fun() { std::cout << “Private_derived::private_fun\n”; }
 };
 int main() {
 Public_derived p;
 p.public_fun(); // allowed, calls Public_derived::public_fun
 p.private_fun(); // allowed, calls Public_derived::private_fun
 p.Base::public_fun(); // allowed, calls Base::public_fun
 p.Base::private_fun(); // NOT allowed, tries to name Base::public_fun
 Private_derived r;
 r.Base::public_fun(); // NOT allowed, tries to call Base::public_fun
 r.Base::private_fun(); // NOT allowed, tries to name Base::private_fun
 }