2012-01-30 88 views
0

我正在用C++编写一个小程序,我该怎么玩多态。
因此,代码是这样的:C++虚拟方法重载/覆盖编译器错误

//Base.h 
class Base{ 
    public: 
     void method(const objectType1& stuff1); 
     //objectType1 is whatever type you what (int, string, ...) 

    protected:  
     Base(void); 
     virtual ~Base(void); 

     virtual void method(void) = 0; 
}; 

//Derived.h 
/*FINAL - DO NOT INHERIT THIS CLASS OR YOU WILL die :)*/ 
class Derived : public Base{ 
    public: 
     Derived(void); 
     ~Derived(void); 

    private: 
     void method(void); 
}; 


//Main.cpp 
int main(){ 
    objectType1 ot1; 

    //this code works 
    Base *bd = new Derived; 
    bd->method(ot1); 

    //this dosen't 
    Derived *dd = new Derived; 
    dd->method(ot1); 
    // he doesn't call Base::method(const objectType1& stuff1), 
    // he calls Derived::method(void) 

    return 0; 
} 

我已经在别的重命名虚拟方法void method(void)解决了这个问题,一切都很好。

我的问题是:

  • 为什么不编译器知道要调用基类中的方法?
  • ,为什么我看到mainvoid method(void)因为它被声明为BaseprotectedDerivedprivate? (这是某种类型的副作用)

谢谢:)。

+0

您标记了您的问题'编译器错误',所以,_什么是编译器errors_? – ildjarn 2012-01-30 22:24:41

+0

是的,'编译器错误'标记不完全正确。 – Daniel 2012-01-31 09:04:15

回答

1

Derived的方法定义隐藏在Base定义。为避免这种情况,请将using Base::method;添加到Derived

发生这种情况是因为在调用Derived中的函数时,编译器只有在Derived中的名称不正确时才会查找Base。请注意,它看起来并不为签名但仅限于在该阶段。基于签名的重载解析仅在之后完成。这实际上是对下面的情况没有太大的不同:

void function(int); 
void function(); 

int main() 
{ 
    void function(); // this declaration hides *both* global declarations 
    function(3); // error 
} 

在你的情况Base起在全球范围内的作用和Derived功能范围的作用。

还要注意virtaul fgunctions这是没有关系的;事实上,如果没有virtual,也会发生同样的情况(除非您通过指向Base的指针的method,当然,但是会改为Base版本)。

+2

术语不正确。派生*中的方法重写*(与基类型中的虚方法相同的签名),而不是*隐藏*(派生类型中的不同签名或非虚方法将隐藏基类型中的成员函数 – 2012-01-30 22:09:30

+1

隐藏是*和*覆盖隐藏是一个名称查找功能,并在调用静态类型“Derived”的对象时发挥作用Overriding是一个运行时功能,并在调用静态类型为“Base”的对象时发挥作用但动态类型'派生'。 – celtschk 2012-01-30 22:29:50

3

在基类的构件的方法是公共的,这意味着任何一段代码可以调用它。除了公开之外,它是虚拟的,这意味着执行将在运行时动态分派给最终的覆盖。

访问方法在静态类型的基准/指针通过其呼叫被调度的被检查静态,即使这将是动态分派。

另一方面,在第二种情况下,通过派生类型进行调用,并在该级别检查访问说明符,其中编译器发现成员函数为private并因此发出抱怨。

在普通的英语,当对象被用作碱,它表现为一个基,而是直接使用时它表现为衍生。