- c语言中,间接赋值是指针存在的最大意义
- c++中多态的三个条件
- 1)有继承
- 2)有虚函数重写
- 3)用父类指针指向子类对象
如果不写virtual关键字会是静态链接编译
#include<iostream>
using namespace std;
class A
{
public:
virtual int power(){
return 10;
}
protected:
private:
};
class B{
public:
int attack(){
return 15;
}
protected:
private:
};
class C: public A{
public:
virtual int power(){
return 20;
}
protected:
private:
};
//封装,封装突破c函数的概念,用类做函数参数的时候,可以使用对象的属性和方法
//继承:A B代码复用
//多态:可以为以后的代码拓展提供接口
//实现多态的三个条件
void conquer(A *base1,B *base2){//多态
if(base1->power() > base2->attack()){
cout<<base1->power()<<endl;
cout<<"正义必胜"<<endl;
}else{
cout<<base1->power()<<endl;
cout<<"魔高一丈"<<endl;
}
}
void conquer2(A &base1,B &base2){//多态
if(base1.power() > base2.attack()){
cout<<base1.power()<<endl;
cout<<"正义必胜"<<endl;
}else{
cout<<base1.power()<<endl;
cout<<"魔高一丈"<<endl;
}
}
void main062601(){
A a1;
C c1;
B b1;
if(a1.power()>b1.attack()){
cout<<"A win"<<endl;
}else{
cout<<"B win"<<endl;
}
if(c1.power()>b1.attack()){
cout<<"C win"<<endl;
}else{
cout<<"B win"<<endl;
}
cout<<"hello"<<endl;
system("pause");
return;
}
void main(){
A a1;
C c1;
B b1;
cout<<a1.power()<<endl;
cout<<c1.power()<<endl;
conquer(&a1,&b1);
conquer(&c1,&b1);
cout<<"hello"<<endl;
system("pause");
return;
}
- 如果写了virtual关键字,是动态联编,也叫迟绑定,运行的时候才会根据具体的对象
- 虚析构
#include<iostream>
using namespace std;
class A
{
public:
A(){
p = new char[20];
strcpy(p,"objA");
cout<<"A"<<endl;
}
virtual ~A(){
delete [] p;
cout<<"~A"<<endl;
}
protected:
private:
char *p;
};
class B : public A
{
public:
B(){
p = new char[20];
strcpy(p,"objB");
cout<<"B"<<endl;
}
~B(){
delete [] p;
cout<<"~B"<<endl;
}
protected:
private:
char *p;
};
class C : public B
{
public:
C(){
p = new char[20];
strcpy(p,"objC");
cout<<"C"<<endl;
}
~C(){
delete [] p;
cout<<"~C"<<endl;
}
protected:
private:
char *p;
};
//执行了父类的析构函数
//想要通过父类指针把子类对象的析构函数全部执行一遍
//通过父类指针释放所有的内存资源只能通过虚析构函数
//核心总结:通过父类指针释放所有子类对象
void howToDelete(A *base){
delete base;//这句话没有表现出多态属性,出现了内存泄漏
}
void main(){
C *myC = new C; // new delete匹配
howToDelete(myC);
//delete myC;通过子类对象释放资源,不需要virtual
//如果想调用父类释放所有资源还是需要虚析构函数
cout<<"hello"<<endl;
system("pause");
return;
}
- 重写重载重定义
- 函数重载,必须在同一个类中,子类无法重载父类的函数,父类同名函数将被覆盖,重载是在编译期间根据参数类型和个数决定函数调用
- 函数重写, 重写发生在子类和父类之间,而且要求完全相同的类型,使用virtual关键字叫多态,如果不使用virtual叫重定义,多态是在运行期间根据具体对象的类型决定函数调用
#include<iostream>
using namespace std;
class A
{
public:
void abc(){
cout<<"abc"<<endl;
}
virtual void fun(){
cout<<"fun() +"<<endl;
}
virtual void fun(int i ){
cout<<"fun() + "<<i<<endl;
}
virtual void fun(int i ,int j ){
cout<<"fun() + "<<i<<j<<endl;
}
protected:
private:
};
class B : public A
{
public:
//想要重载父类的abc,但是子类无法重载父类的函数
void abc(){
cout<<"B abc"<<endl;
}
virtual void fun(int i ){
cout<<"B :fun(int i ) + "<<i<<endl;
}
virtual void fun(int i ,int j ){
cout<<"B:fun(int i ,int j) + "<<i<<j<<endl;
}
protected:
private:
};
class C : public B
{
public:
protected:
private:
};
void main(){
B b1;
b1.abc();
//子类的发生了名称覆盖,子类函数的名字,占用了父类的函数的名字的位置
b1.A::abc();
cout<<"hello"<<endl;
system("pause");
return;
}
- c++编译器只会在子类中,如果父类存在4个参数的fun函数,而子类中却不存在,当进行调用的时候不会自动取父类中寻找,就会报错,必须使用作用域来进行调用。