目录
虚函数介绍
虚函数、覆盖和重载区别
虚函数介绍
C++的虚函数是多态性的表现
1.构造函数不能为虚函数 |
2.子类继承时虚函数仍为虚函数 |
3.虚函数类外实现时,不需要加virtual |
4.有虚函数的类,析构函数一定要写成虚函数(否则可能会造成内存泄漏) |
5.纯虚函数不能实例化,子类必须实现父类虚函数,否则也不能实例化 |
class A
{
public:
virtual A(){} //报错:“A”:“inline”是构造函数的唯一合法存储类
}
class A
{
public:
A(){ cout << "A() " << endl; }
virtual void print(void) { cout << "A::print() " << endl; }
};
class B : public A
{
public:
B() { cout << "B() " << endl;}
void print(void) { cout << " B::print() " << endl; }//虽然没有写virtual,但继承来自A,所以仍然为virtual。但强烈建议写上virtual
};
class C : public B
{
public:
C() { cout << "C() " << endl; }
virtual void print(void);
}
void C::print(void) //类外实现函数体时不需要加 virtual
{
cout << "C::print()!" << endl;
}
int main(void)
{
A *a = new C;
a->print(); //打印 C::print()!
return 0;
}
class A
{
public:
A(){}
virtual void print(void) = 0;
};
class B : public A
{
public:
B(){}
//此处没有对print进行实现
};
int main()
{
// A a; //报错,“A”: 无法实例化抽象类
// B b; //报错,“B”: 无法实例化抽象类
return 0;
}
class A
{
public:
A() { cout << "A()" << endl;}
virtual void print(void) { cout << "A::print()!" << endl; }
~A() { cout << "~A()" << endl; } //此处析构函数未声明为virtual
};
class B : public A
{
public:
B() { cout << "B()" << endl; }
virtual void print(void) { cout << "B::print()" << endl; }
~B() { cout << "~B()" << endl; }
};
int main(void)
{
A *a = new B;
a->printf();
delete a; //注意看下面执行结果打印
return 0;
}
执行结果如下,只执行了类A的析构函数,new出来的B的析构没有执行,内存泄漏
当A的析构函数声明为virtual,则先执行B的析构函数,在执行A的析构函数
虚函数、覆盖和重载区别
虚函数:父类某成员函数必须用virtual声明,子类重写的函数定义完全与父类相同(参数类型,参数个数和返回值),发生在父类和子类之间,父类可以调用子类的函数
覆盖:父类成员函数不用virtual声明,子类成员函数名称与父类相同(参数类型,参数个数和返回值可以不同),子类则完全覆盖父类所有相同名称的函数(即子类不能访问父类相同函数名称的函数)
重载:同一类的类成员函数之间,成员函数名称相同,但成员函数的参数类型、参数个数必须有至少一项不同