无法识别的继承功能

时间:2014-06-22 13:12:59

标签: c++ inheritance

在Visual C ++ 2010上运行此C ++源:

class B{
public:
    virtual void f(int a){}
    virtual void f(){}
};
class A:public B{
public:
    virtual void f(int a){}
};
int main(){
A a;
a.f();
return 0;
}

导致以下错误:

IntelliSense: too few arguments in function call

换句话说,似乎void f()没有继承?

有什么问题?

3 个答案:

答案 0 :(得分:7)

  

似乎void f()没有继承?

A类中的名称f 阴影在B中命名为f。您仍然可以通过这种方式从B访问foo()

A a;
a.B::f();

其他选项是在A:

的范围内重新声明B的函数foo
class A : public B{
public:

    virtual void f(int a) {}
    using B::foo;
};

C ++标准版n3337 § 10.2会员名称查找

  

1)成员名称查找确定名称的含义(id-expression)   在一个范围内(3.3.7)。名称查找可能导致歧义   在哪种情况下,该计划是不正确的。对于id-expression,名称   查询从此类的范围开始;对于限定ID,名称   查询从嵌套名称说明符的范围开始。名称查找   在访问控制之前进行(3.4,第11条)。

     

2)以下步骤定义成员的名称查找结果   在类范围C中命名为f。

     

3)C中f的查找集,称为S(f,C),由两个组成   组件集:声明集,一组名为f的成员;和   子对象集,一组子对象,其中声明了这些成员   (可能包括使用声明)被发现。在宣言中   set,using-declarations由他们指定的成员替换,   和类型声明(包括inject-class-names)替换为   他们指定的类型。 S(f,C)计算如下:

     

4)如果C包含名称为f的声明,则声明集   包含在C中声明的满足f的每个声明   查找发生的语言构造的要求。 [   注意:在精心设计的类型说明符(3.4.4)或中查找名称   例如,base-specifier(第10条)忽略所有非类型   声明,同时在嵌套名称说明符中查找名称   (3.4.3)忽略函数,变量和枚举器声明。如   另一个例子,在using声明中查找名称(7.3.3)   包括声明的类或枚举   通常被该名称的另一个声明所隐藏   范围。 - 结束注释]如果生成的声明集不为空,则为   子对象集包含C本身,计算完成。

     

5)否则(即C不包含f或f的声明)   结果声明集为空),S(f,C)最初为空。如果是C.   有基类,计算每个直接基数中f的查找集   class subobject Bi,依次合并每个这样的查找集S(f,Bi)   进入S(f,C)。

答案 1 :(得分:5)

您的A::f(int a)声明会隐藏所有签名B::f,除非它们暴露给派生类。曝光“隐藏”方法有两个很好的选择。

选项1

class A:public B{
public:
    using B::f;
    virtual void f(int a){}
};

选项2

class A:public B{
public:
    virtual void f(int a){}
    virtual void f(){ B::f(); }
};

答案 2 :(得分:0)

1)你必须使用指针。 2)如果你想获得A :: f(),你必须使用A *类型变量,但类实例可以是B *或A *类型。

    #include <iostream>
    using namespace std;
    class A {
    public:
        virtual void f(int a) {cout << a << " A::f(int)" << endl; }
        virtual void f(){cout << 5 << " A::f()" << endl;}
    };
    class B:public A {
    public:
        virtual void f(int a) {cout << a+1 << " B::f(int)" << endl; }
    };
    int main() {
        A *a;
        a = new B();
        a->f(1);
        a->f();
        delete a;
        a = new A();
        a->f(1);
        a->f();
        delete a;
        return 0;
    }

输出:

    2 B::f(int)
    5 A::f()
    1 A::f(int)
    5 A::f()