2014-04-01 108 views
0

我有4重载函数vfoo(3是虚拟的)重载函数(虚拟/非虚拟)

我想在这里测试几个概念:

  1. 使用虚拟函数
  2. 重载重载当派生类实现了自己的重载函数版本时,派生类中隐藏了函数。
  3. 什么是当一个基类指针存储在状空隙vfoo派生类(炭X)
#include<iostream> 
using namespace std; 

/*Base class having 4 overloaded function*/ 
class ClassBaseV 
{ 
    public: 

     virtual void vfoo(int x) { 
       cout << "ClassBaseV vfoo(int), x = " << x << endl; 
     } 

     virtual void vfoo(double x) { 
       cout << "ClassBaseV vfoo(double), x = " << x << endl; 
     } 

     virtual void vfoo(int x, double y) { 
       cout << "ClassBaseV vfoo(int,double), x = " << x << ", y = " << y << endl; 
     } 

     void vfoo(double x, int y) { 
       cout << "ClassBaseV vfoo(double,int), x = " << x << ", y = " << y << endl; 
     } 
}; 


class ClassDerived1 : public ClassBaseV 
{ 
    public: 

     //Overloaded with char x 
     void vfoo(char x) { 
       cout << "ClassDerived1 vfoo(char), x = " << x << endl; 
     } 


     //over riding int x 
     void vfoo(int x) { 
       cout << "ClassDerived1 vfoo(int), x = " << x << endl; 
     } 


}; 


int main() 
{ 
    ClassBaseV *cB = new ClassDerived1(); /*Base pointer storing derived class object*/ 
    ClassDerived1 *cd1 = new ClassDerived1(); //Derived class object 
    cd1->vfoo('a');//Direct call using derived class object. this works 
    char a = 'a'; 
    cB->vfoo(a); // trying to call char x using cB. This calls derived class int How? 
    cB->vfoo(10); // trying to call int x using CB. This calls derived class int 
    cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but this works 

    return 1; 
} 
+0

输出 ClassDerived1 vfoo(炭),X = A ClassDerived1 vfoo(INT)中,x = 97 ClassDerived1 vfoo(INT)中,x = 10 ClassBaseV vfoo(双)中,x = 2.2 – user2432444

+0

如果你实现了一个重载集的一些函数,那么添加一个使用声明让其他人进入范围是普通的。节省使用上的尴尬失败... – Deduplicator

回答

0

第一个问题派生类对象

  • 重载函数的行为:

    cB->vfoo(a); 
    

    当你在这里调用vfoo时,它会尝试在ClassBaseV中找到vfoo(char x)的定义,但它不会,但仍然找到可隐式转换的vfoo(int x)的定义,因此它会调用此方法d来自ClassBaseV。

    编译器将尝试获取作为类型提供的类的方法的定义。

    ClassBaseV *cB = new ClassDerived1(); 
    

    在这一行上,键入cB作为指向ClassBaseV的指针。从现在起,编译器无法在子类中查找方法定义(但在子类中),但仍然可以提高优势,因为ClassBaseV已知可能会继承父类。

    第二个问题:

    cB->vfoo(2.2); 
    

    在这条线,你调用方法vfoo(双X)作为转换翻一番可在ClassBaseV,你不覆盖在ClassDerived1此方法。

    因此,调用此方法的ClassBaseV实现是一种正常行为。

    如果你想调用的ClassDerived1重写的vfoo之一,你必须将它转换为int或字符(和松散的信息)

    cB->vfoo(static_cast<int>(2.2)); 
    

    或ClassDerived1添加一个新方法重写vfoo (double x)从ClassBaseV。

    另外,如果你想强制ClassDerived1实现方法vfoo(双X)从ClassBaseV,你必须声明为纯虚:

    virtual void vfoo(double x) = 0; 
    
  • 0

    如果替换设置过载的一部分,一个派生类,通常的做法是通过声明using将所有未覆盖的函数放入范围。防止尴尬失败。在基地

    cB->vfoo(a); // trying to call char x using cB. This calls derived class int How? 
    

    重载分析获取到最接近的匹配(字符 - > int)和呼叫使用虚拟调度

    cB->vfoo(10); // trying to call int x using CB. This calls derived class int 
    

    Exect匹配在ovrload分辨率和虚拟调度到的。

    cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but 
    

    重载分辨率的精确匹配,虚拟调度到基地。

    切勿尝试去除派生类中的要素。

    接口继承意味着:我至多需要保证库需求,而且我的行为符合基础合同。

    0

    “基类指针存储派生类对象时的行为是什么” - 这是多态的核心思想。 多态性是基于在运行时间中确定的基于对象类型的特定行为而重载函数在编译时间中解决的。常量文字的

    类型可以在编译时10int容易地被确定,2.2double,这将决定哪些成员函数将被使用。实例的类型将决定使用哪个实现(哪个类)。下面是简单的例子:

    class Animal { 
    public: 
        virtual void makeSound(){ std::cout << "hi" << std::endl; } 
        virtual void makeSound(int pain){ std::cout << "ouch" << std::endl; } 
        virtual void makeSound(double d){ std::cout << "aaaaaaaargh" << std::endl; } 
    }; 
    
    class Cat : public Animal { 
    public: 
        virtual void makeSound(){ std::cout << "meow" << std::endl; } 
        virtual void makeSound(int pain){ std::cout << "MEEEEEOW!!!" << std::endl; } 
        virtual void makeSound(double d){ std::cout << "meow double" << std::endl; } 
    }; 
    
    int main() { 
        Animal *a = new Animal(); 
        Animal *cat = new Cat(); 
        a->makeSound(); 
        cat->makeSound(); 
        a->makeSound(100); 
        cat->makeSound(100); 
        cat->makeSound(750.80); 
    } 
    

    输出:



    哎哟
    MEEEEEOW!
    喵双