使用子方法c ++

时间:2013-11-17 18:49:21

标签: c++ polymorphism

我有这些对象:

class A{
    public:
        void print();
}

class B : public A{
    public:
        void print();
}

class C : public A{
    public:
        void print();
}

功能打印:

void A::print(){
    cout << "A" << endl;
}

void B::print(){
    cout << "B" << endl;
}

void C::print(){
    cout << "C" << endl;
}

现在我有一个A对象的向量,可以包含A B或C

for(unsigned int i = 0; i<m_vA.size(); i++)
{
    cout << m_vA[i]->print() << endl;
}

但每次函数返回A时,即使这是一个B或C对象

感谢您的帮助

4 个答案:

答案 0 :(得分:3)

您不会覆盖该功能。为此,请在A类中声明此函数时使用“virtual”关键字。

答案 1 :(得分:2)

您忘了将成员函数虚拟

答案 2 :(得分:2)

简短的回答是:使用virtual作为其他答案指示,以便您覆盖该功能,而不是隐藏它。

以下摘录自Herb Sutter的 Exceptional C ++ - 第21项:覆盖虚拟函数,它更详细地解释了代码的用途:

  

区分三个常用术语非常重要:

     
      
  • 重载函数f()意味着在同一范围内提供具有相同名称f()的另一个函数但具有不同的功能   参数类型。实际调用f()时,编译器会尝试   根据实际参数选择最佳匹配   提供。

  •   
  • 覆盖虚拟函数f()意味着提供另一个具有相同名称f()的函数和相同的参数类型   派生班。

  •   
  • 在封闭范围(基类,外部类或命名空间)中隐藏函数f()意味着提供具有相同功能的另一个函数   内部作用域中的名称f()(派生类,嵌套类或   命名空间),它将在封闭中隐藏相同的函数名称   范围。

  •   

因为您的各种print函数都在嵌套作用域中,并且因为您没有提供virtual关键字,所以每个函数都隐藏中的同名函数基类:

class A{
    public:
        void print();
}

class B : public A{
    public:
        void print(); // Hides A::print()
}

class C : public A{
    public:
        void print(); // Hides A::print() and B::print()
}

因此,当编译器执行名称解析时,它将在当前范围内查找(这是您调用该函数的类型的类定义),它将停在那里,因为它将找到非虚函数名称为print

答案 3 :(得分:0)

多态性需要使用virtual关键字来声明该方法应存储在虚拟表( vtable )中,并在运行时查找其实现。 另请注意,您的类定义在结束括号后需要使用分号。

class A
{
public:
    virtual void print()
    {
        cout << "A" << endl;
    }
};

class B : public A
{
public:
    virtual void print() override
    {
        cout << "B" << endl;
    }
};

class C : public A
{
public:
    virtual void print() override
    {
        cout << "C" << endl;
    }
};

在旁注中,派生类中的virtual关键字不是必需的(如果基类函数被声明为虚拟,则隐式添加在派生类中),但是为了可读性和避免潜在问题很好用与需要它的奇怪编译器。 override标识符也不是必需的,但会强制编译器检查您实际上是否覆盖了超类中存在的虚函数。 (我认为覆盖仅适用于C ++ 11)。