我正在学习多态,并尝试了一些基本的东西。在下面的代码中,我在基类s = pd.read_csv(StringIO(the_data), sep='|', header=None, squeeze=True)
left = s.str.split(',').str[:3].apply(pd.Series)
left.columns = ['Company', 'Date', 'Volume']
right = s.str.split(',').str[3:].str.join(',') \
.str.replace(r'[\[\]\{\}\']', '') \
.str.replace(r'(:\s+\d+)L', r'\1') \
.str.split(',', expand=True)
right.columns = ['Car{}'.format(i) for i in range(1, 5)]
pd.concat([left, right], axis=1)
中有一个虚函数display()
。我创建了两个派生类Animal
,继承自Dog
继承的Animal
和Tommy
。 Dog
函数仅在以下代码中的一个派生类(display()
类中重写)。
在Tommy
函数中,我通过基类指针指向派生对象。我认为以下代码片段会给我一个错误。
main()
但是,它最终调用ptr = &dog;
ptr->display();
的父类的display()
(i,e。Dog
)。出于好奇,我删除了Animal
函数其他派生类并检查输出,但我得到相同的行为,总是最终调用父类的display()
。我不知道为什么会发生这种情况。我想我在这里遗漏了一些东西。请发布。帮助
display()
输出结果为:
#include <iostream>
using namespace std;
class Animal
{
protected:
string name;
public:
Animal(string nam):name(nam){}
virtual void display()const {cout<<"Base class.\n";}
};
class Dog : public Animal
{
public:
Dog(string nam):Animal(nam){}
};
class Tommy : public Dog
{
public:
Tommy(string nam):Dog(nam){}
void display()const{cout<<"i am "<<name<<endl;}
};
int main()
{
Animal *ptr;
Dog dog("trace");
Tommy tom("tommy");
ptr = &dog;
ptr->display();
ptr = &tom;
ptr->display();
return 0;
}
答案 0 :(得分:1)
但是,它最终调用了Dog(即动物)的父类的display()。
这是完全预期的行为,因为您没有覆盖派生类display
中的虚函数Dog
。
为了使派生类具有特定行为,您必须实现非纯虚函数display
。您已经在Tommy
类中实现了该函数,但在Dog
类中没有这样的实现。
答案 1 :(得分:1)
第一次显示值时,它是Dog类型。 Dog没有重新定义显示,它使用Animal中的一个,因为它继承了这个功能。
第二次显示值时,它是Tommy类型。汤米重新定义了显示功能,即“我是汤米”。它将显示此字符串,因为它重新定义了此虚函数。
这是因为Tommy是动物,因为Tommy继承了继承Animal的Dog。可以这样想:每个Tommy都是动物,但不是每个动物都是Tommy也不是狗。
Virtual是C ++中的关键字,这意味着可以在子类中重新定义函数。
编辑:只是澄清什么是纯虚函数和虚函数。纯虚函数声明函数NEEDS将在其子类中重新定义,或者它将不会编译(即,此函数的基类中没有实现)。虚函数表明它可以在他的子类中重新定义(它在基类中有一个实现)。在此示例中,display是一个虚函数,而不是纯函数。