2012-03-31 84 views
1

我了解虚拟功能和运行时调用的基本概念。但我想 运行某些部分的代码,让我感到困惑有人可以解释这个虚拟功能的行为?

class A { 
    public: 
    A& operator=(char) { 
     cout << "A& A::operator=(char)" << endl; 
     return *this; 
    } 
    virtual A& operator=(const A&) { 
     cout << "A& A::operator=(const A&)" << endl; 
     return *this; 
    } 
    }; 

    class B : public A { 
    public: 
     B& operator=(char) { 
     cout << "B& B::operator=(char)" << endl; 
     return *this; 
     } 

     virtual B& operator=(const B&) { 
     cout << "B& B::operator=(const B&)" << endl; 
     return *this; 
     } 
    }; 

    int main() { 
    B b1; 
    B b2; 
    A* ap1 = &b1; 
    A* ap2 = &b1; 
    *ap1 = 'z'; 
    *ap2 = b2; 
    } 

运行该程序给我下面的输出: -

A& A::operator=(char) //expected output 
    A& A::operator=(const A&) //Why this Output? in case of *ap2 = b2; 

b2B类型的对象,但它仍然进入虚拟A& operator=(const A&) 而不是虚拟B& operator=(const B&)。这是为什么?

回答

3

因为virtual B& operator=(const B&)不会覆盖virtual A& operator=(const A&);争论是不同的。

+0

Chalesworth的有效形式,从而是,该函数调用,而不是种中的指针类型的事项对象是指向的指针,哪个实际发生在虚函数的情况下?因为这里ap2是A的指针类型,但指向B类型的对象?我在哪里错了? – Invictus 2012-03-31 19:25:35

+1

@Ritesh:在'* ap2 = b2'行,'* ap2'的编译时类型是'A'。因此,编译器只能考虑在“A”呈现的接口中存在的(虚拟)成员函数。 – 2012-03-31 19:26:59

2

对于派生类函数重写基类函数,派生类函数需要具有完全相同的功能的原型(例外:协变返回类型被允许)。

=运营商在派生B这里类不具有相同的函数原型为=在基地A类,因此它不会重写基类=

唯一=运营商可以为这就是所谓的一个。

2

对于函数被认为超驰的签名具有精确匹配在临基类中的版本(当然,如果返回一个指针或参考返回类型可以是协变)。也就是说,您需要定义

B& B::operator= (A const&) 

覆盖基类的版本。请注意,对于覆盖函数中的输入参数,协变是没有意义的,因为您无法保证在仅使用基类的上下文中使用派生对象调用基类版本。如果重写函数的任何参数都可能是逆变的,但C++不支持这一点。

2

在这里,在其拍摄A.所以,基本上其不被重写为函数参数的派生类的功能被服用B而在基类是不同的。

另请注意,重写时的返回类型可能与您的情况不同,因为您正在返回基准中的A引用和派生中的B引用。 虚拟基础& FUNC(常量基地&) 虚拟衍生& FUNC(常量基地&) 这是首要

相关问题