简体   繁体   English

C ++虚拟方法重载/重写编译器错误

[英]C++ virtual method overload/override compiler error

I'm writing a little program in C++ and I what to play with polymorphism. 我正在用C ++编写一个小程序,该如何处理多态性。
So the code goes like this: 因此,代码如下所示:

//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;
}

I've solved the problem by renaming the virtual method void method(void) in something else and all is well. 我已经通过将虚拟方法void method(void)重命名为其他方法解决了问题,一切都很好。

My questions are: 我的问题是:

  • Why doesn't the compiler know to call the method from the base class? 为什么编译器不知道从基类调用该方法?
  • And why do I see void method(void) in main since it is declared as protected in Base and private in Derived ? 又为什么在main看到void method(void) ,因为它在Base声明为protected ,在Derived private (is this some sort of side effect) (这是某种副作用)

Thanks :) . 谢谢 :) 。

The member method in the base class is public, which means that any piece of code can call it. 基类中的成员方法是公共的,这意味着任何代码段都可以调用它。 Besides being public, it is virtual, which means that the execution will be dynamically dispatched at runtime to the final overrider. 除了公开之外,它是虚拟的,这意味着执行将在运行时动态分派到最终的替代程序。

Access to the method is checked statically in the static type of the reference/pointer through which the call is dispatched, even if it will be dynamically dispatched. 将以分派调用的引用/指针的静态类型静态检查对方法的访问,即使该分派将被动态分派。

On the other hand in the second case, the call is through the derived type, and the access specifier is checked at that level, where the compiler finds the member function to be private and thus complains. 另一方面,在第二种情况下,调用是通过派生的类型进行的,并且在该级别检查访问说明符,在该级别编译器发现成员函数是private ,因此进行了抱怨。

In plain english, when the object is used as a base, it behaves as a base, but when used directly it behaves as derived. 用简单的英语来说,当对象用作基础时,它的行为就像是基础,但是当直接使用对象时,它的行为就像派生的。

The method definition in Derived hides the definition in Base . Derived的方法定义隐藏了Base的定义。 To avoid that, add using Base::method; 为了避免这种情况,请using Base::method;添加using Base::method; to Derived . Derived

This happens because when calling functions in Derived , the compiler looks into Base only if it didn't fine the name in Derived . 发生这种情况是因为,当在Derived调用函数时,仅当编译器未对Derived的名称进行罚款时,编译器才会查找Base Note that it doesn't look for the signature but only for the name in that stage. 请注意,它不查找签名,而仅查找该阶段的名称 Overload resolution based on the signature is done only afterwards. 仅在之后才执行基于签名的重载解析。 This is actually not much different to the following situation: 实际上,与以下情况没有太大区别:

void function(int);
void function();

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

In your case Base plays the role of the global scope and Derived the role of the function scope. 在您的情况下, Base充当全局范围的角色,而Derived充当功能范围的角色。

Also note that this is not related to virtaul fgunctions; 还要注意,这与虚拟功能无关。 indeed the same would happen without virtual (except that you then couldn't call Derived 's method via a pointer to Base , of course, but would call the Base version instead). 确实,如果没有virtual ,同样会发生(除了您不能通过指向Base的指针调用Derivedmethod ,当然,而是调用Base版本)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM