#include<iostream>
using namespace std;
class A
{
public:
void print(int a)
{
cout << a + 1 << endl;
}
virtual void print_v(int a)
{
cout << a + 1 << endl;
}
};
class B :public A
{
public:
void print(int a)
{
cout << a + 2 << endl;
}
void print_v(int a)
{
cout << a + 2 << endl;
}
};
void main()
{
A* a = new B();
a->print(0);
a->print_v(0);
}
结果:
错误1:不允许对不可访问的基类进行转换
#include<iostream>
using namespace std;
class Fuck{
protected:
virtual void fuck(){};
Fuck(){
this->fuck();
}
};
class SubFuck :protected Fuck
{
protected:
void fuck(){
cout << "do sub fuck" << endl;
}
};
int main(){
Fuck f = SubFuck();//不允许对不可访问的基类进行转换
int a;
cin >> a;
}
因为Fuck是protected继承SubFuck的,意味着这种继承关系只能在SubFuck及其子类内部可见。在main函数里面做Fuck f = SubFuck();数非法的,因为main函数里面根本不知道SubFuck继承自Fuck
应该改成class SubFuck :public Fuck
错误2:无法解析的外部符号
无法解析的外部符号 "protected: virtual void __thiscall Fuck::fuck(void)" (?fuck@Fuck@@MAEXXZ),该符号在函数 "protected: __thiscall Fuck::Fuck(void)" (??0Fuck@@IAE@XZ) 中被引用
1>C:\Users\Yu Yong\Desktop\Test\Project1\Debug\Project1.exe : fatal error LNK1120: 1 个无法解析的外部命令
#include<iostream>
using namespace std;
class Fuck{
protected:
virtual void fuck();
Fuck(){
this->fuck();
}
};
class SubFuck :public Fuck
{
protected:
void fuck(){
cout << "do sub fuck" << endl;
}
};
int main(){
Fuck f = SubFuck();
int a;
cin >> a;
}
这是因为virtual void fuck();既然是虚函数(不是纯虚函数),那么就要定义方法体,即使是空实现
应该为virtual void fuck(){};
错误3:不能实例化抽象类
#include<iostream>
using namespace std;
class Fuck{
public:
virtual void fuck()=0;
};
class SubFuck :public Fuck
{
protected:
void fuck(){
cout << "do sub fuck" << endl;
}
};
int main(){
Fuck f =SubFuck();//不能实例化抽象类
f->fuck();
int a;
cin >> a;
}
Fuck包含纯虚函数,不能直接申明实例。但是可以申明指针,所以应该为Fuck* f =new SubFuck();
虚析构函数
为什么需要虚析构函数?
class B : A,A里面有虚函数funA,这样我们用A* ptr_a指向B然后调用ptr_a->funA()这样就能实现多态。这是我们需要虚函数的理由。
但是在析构的时候就遇到了麻烦。如果析构函数不是虚的。那么析构函数就不是多态的,delete ptr_a,这样明明是指向B的指针却只能调用A里面定义的析构函数,这样就会造成B里面有部分(在A基础上追加的部分)内存得不到释放,这样就会造成内存泄漏。所以:
当且仅当一个类被作为基类的时候,这个类的析构函数应当为虚!