理解(简单?)C ++继承 [英] Understanding (simple?) C++ Inheritance

查看:109
本文介绍了理解(简单?)C ++继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在努力了解为什么这段程式码片段无法编译。

  #include< cstdio& 

class A {
public:
virtual int potential()= 0;
virtual int potential(int arg,int arg2)= 0;
};

class B:public A {
public:
int potential(){return 1; }
virtual int potential(int arg,int arg2){return 2; }
};

class C:public B {
public:
int potential(int arg,int arg2){return 3; }
};


int main(int argc,char ** argv){
C c;
int value = c.potential();
printf(Got%i\\\
,value);
return 0;
}



我有两个纯虚方法,分别命名为 在抽象超类 A 中。子类 B 然后定义两者,但是另一个子类 C 只需要重新定义其中一个方法。



但是,在编译时,只识别在 C 中定义的方法, / code>没有看到(这应该是继承自 B ):

 在函数'int main(int,char **)':
行23:错误:没有匹配的函数调用'C :: potential()'
编译终止由于-Watalatal错误。

如果我重命名 A :: potential(int,int)到继承树的所有位置,如 A :: somethingElse(int,int),那么代码编译得很好,输出是有预期的

$ 1 $ / $ c $

已经使用 clang > g ++ 和MSVC的 cl



有什么想法吗?


C ++不工作像这样:因为你实现了一个不同的潜力 C 中,c $ c>方法(同名但是具有不同参数的方法),另一个方法是 hidden C $ c> C



隐藏发生的原因是C ++解析在类的实例( c )上的潜在,C ++在类中搜索该名称的方法是否存在。如果不是这样,它继续在基类中的搜索。



但是在你的情况下,C ++不需要搜索far:该方法已经存在于 C 中,因此停止其搜索。现在C ++尝试匹配方法签名。不幸的是,方法签名不匹配,但在这时候太晚了:重载解析失败; C ++不搜索可能匹配的其他方法。



有三种解决方案:


  1. 使用在C:

    中使用导入它

      class C:public B {
    public:
    using B :: potential;
    int potential(int arg,int arg2){return 3; }
    };


  2. code>:

      C c; 
    B& b = c;
    int value = b.potential();


  3. main中明确限定名称

      C c; 
    int value = c.B :: potential();



I'm struggling a bit to understand why this code snippet does not compile.

#include <cstdio>

class A {
public:
    virtual int potential()=0;
    virtual int potential(int arg, int arg2)=0;
};

class B : public A {
public:
    int potential() { return 1; }
    virtual int potential(int arg, int arg2) { return 2; }
};

class C : public B {
public:
    int potential(int arg, int arg2) { return 3; }
};


int main(int argc, char** argv) {
    C c;
    int value = c.potential();
    printf("Got %i\n", value);
    return 0;
}

I have two pure virtual methods, both named potential in the abstract superclass A. The subclass B then defines both, but a further subclass C only needs to redefine one of the methods.

However, on compilation, only the method defined in C is recognized, and potential() isn't seen (this should have been inherited from B):

In function 'int main(int, char**)':
Line 23: error: no matching function for call to 'C::potential()'
compilation terminated due to -Wfatal-errors.

If I rename A::potential(int, int) to something else all the way down the inheritance tree, such as A::somethingElse(int, int), then the code compiles fine, and the output is Got 1, as expected.

This has been verified using clang, g++ and MSVC's cl.

Any ideas on what is going on?

解决方案

However, on compilation, only the method defined in C is recognized, and potential() isn't seen (this should have been inherited from B).

C++ doesn’t work like this: because you implemented a different potential method (a method of the same name but with different parameters) in C, the other method is hidden as far as C is concerned.

Hiding happens because of the way that C++ resolves (overloaded) method names: when you call a method potential on an instance of a class (here c), C++ searches in the class whether a method of that name exists. If that isn’t the case it continues its search in the base classes. It goes further up in the hierarchy until at least one method of that name is found.

But in your case, C++ doesn’t have to search far: the method already exists in C, so it stops its search. Now C++ tries to match the method signature. Unfortunately, the method signature doesn’t match but at this time it’s too late: overload resolution fails; C++ doesn’t search for other methods that might match.

There are three solutions:

  1. Import it with using in C:

    class C : public B {
    public:
        using B::potential;
        int potential(int arg, int arg2) { return 3; }
    };
    

  2. Call the method from a base class instance in main:

    C c;
    B& b = c;
    int value = b.potential();
    

  3. Qualify the name explicitly in main:

    C c;
    int value = c.B::potential();
    

这篇关于理解(简单?)C ++继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆