虚函数会自动继承,不管经历多少次继承,派生类都会保持虚特性。
子类中如果没有覆盖父类中的虚函数,而是重载的话,在子类中的虚函数都会存放子类和父类的虚函数,但是虽然是同名,父类的虚函数放在前面,所以先调用父类的虚函数,从而丢失了虚特性。
class Base
{
public:
Base(){func1();}
virtual void func1()
{
cout<<"Base1111111111111111"<<endl;
}
virtual void func2()
{
cout<<"Base2222222222222222222"<<endl;
}
~Base(){func2();}
};
class Sub:public Base
{
public:
// Sub(){func1();}
virtual void func1()
{
cout<<"Sub11111111111111111"<<endl;
}
virtual void func2()
{
cout<<"Sub222222222222222222"<<endl;
}
~Sub(){func2();}
};
int _tmain(int argc, _TCHAR* argv[])
{
Sub sub;
system("pause");
return 0;
}
创建子类之前,肯定是先创建父类。父类的构造函数先出,然后才是子类。有的书上说这是子类的静态联编,肯定是错的。而是如果子类中没有构造函数和析构函数,无法显示。所以调用函数的是父类才对。
3.虚析构函数
class Base
{
public:
Base(){func1();}
void func1()
{
cout<<"Base1111111111111111"<<endl;
}
void func2()
{
cout<<"Base2222222222222222222"<<endl;
}
~Base(){func2();}
};
class Sub:public Base
{
public:
Sub(){func1();}
void func1()
{
cout<<"Sub11111111111111111"<<endl;
}
void func2()
{
cout<<"Sub222222222222222222"<<endl;
}
~Sub(){func2();}
};
int _tmain(int argc, _TCHAR* argv[])
{
Base* base = new Sub;
delete base;
system("pause");
return 0;
}
子类的析构函数没有调用,如果把父类的析构函数变为virtual的,就会一起销毁。
原因是子类中的虚函数表赋给了父类,delete base其实是调用的子类的析构函数,加上只要析构了子类,父类自然就析构了(编译器会悄悄地在子类的析构函数尾部加上父类析构函数的调用)。
本文出自 “郭俊的博客” 博客,转载请与作者联系!
原文地址:http://10093949.blog.51cto.com/10083949/1638135