虚函数用法总结
程序员文章站
2024-03-21 12:01:46
...
#include<iostream>
using namespace std;
class Class {};
class Base :public Class
{
public:
Base() = default;
Base(const Base&a) :ival(a.ival), dval(a.dval)
{
cout << "---Base----" << endl;
}
Base(int a, int b) :ival(a), dval(b)
{
cout << "---Base-a----" << endl;
printf("a11= %d,b11= %d\n", a, b);
}
// virtual void print(){
// printf("%d---1---%d\n",dval,ival );
// }
void print() {
printf("%d---1---%d\n", dval, ival);
}
int dval;
protected:
int ival;
};
class D1 : public Base//因为是虚基,因此可以有不同形参的同名函数print;若不是虚基,则不可以有不同形参的同名函数
{
public:
D1() = default;
D1(const D1&a) :Base(a.ival, a.dval)
{
cout << "---D1----" << endl;
}
D1(int a, int b) :Base(a, b)
{
cout << "---D1-a----" << endl;
}
// void print(int a)
// {
// printf("---2---%d----2---\n", a);
// }
};
int main()
{
D1*pi;
int i = 4, j = 7;
pi = new D1(i, j);
//对于Mi而言,使用Final中的Mi类进行初始化
Base*pmi = new Base(*pi);//指向虚基类,但并未初始化
pi->print(111);
}
#include<iostream>
using namespace std;
class Class {};
class Base :public Class
{
public:
Base() = default;
Base(const Base&a) :ival(a.ival), dval(a.dval)
{
cout << "---Base----" << endl;
}
Base(int a, int b) :ival(a), dval(b)
{
cout << "---Base-a----" << endl;
printf("a11= %d,b11= %d\n", a, b);
}
// virtual void print(){
// printf("%d---1---%d\n",dval,ival );
// }
void print() {
printf("%d---1---%d\n", dval, ival);
}
int dval;
protected:
int ival;
};
class D1 : public Base//因为是虚基,因此可以有不同形参的同名函数print;若不是虚基,则不可以有不同形参的同名函数
{
public:
D1() = default;
D1(const D1&a) :Base(a.ival, a.dval)
{
cout << "---D1----" << endl;
}
D1(int a, int b) :Base(a, b)
{
cout << "---D1-a----" << endl;
}
void print()
{
printf("---2---%d----2---\n", ival);
}
};
class D2 :virtual public Base
{
public:
D2() = default;
D2(const D2&a) :Base(a.ival, a.dval)
{
cout << "---D2----" << endl;
}
D2(int a, int b) :Base(a, b)
{
cout << "---D2-a----" << endl;
}
};
class Mi :public D1/*,public D2*/
{
public:
Mi() = default;
Mi(const Mi&a) :Base(a.ival, a.dval)/*,D2(a.ival,a.dval)*/, D1(a.ival, a.dval)
{
cout << "---Mi----" << endl;
}
Mi(int a, int b) :Base(a, b), D1(a, b)/*,D2(a,b)*/
{
cout << "---Mi-a----" << endl;
printf("a= %d,b= %d\n", a, b);
}
};
class Final : public Mi, public Class
{
public:
Final() = default;
Final(const Final&a) :Base(a.ival, a.dval), Mi(a.ival, a.dval)
// Final(const Final&a):Base(a.ival,a.dval),Mi(1,2)
{
cout << "---Final----" << endl;
}
// Final(int a,int b):Base(a,b),Mi(a,b)
Final(int a, int b) :Base(a, b), Mi(1, 2)//首先Base被Base初始化了,然后Mi中的Base基类初始化就不再调用了
{
cout << "---Final-a----" << endl;
}
};
int main()
{
Final*pi;
int i = 4, j = 7;
pi = new Final(i, j);
//对于Mi而言,使用Final中的Mi类进行初始化
Mi*pmi = new Mi(*pi);//指向虚基类,但并未初始化
pmi->print();
}
两段代码,可以调着进行理解使用
1. 只有一个基被标记为虚基,才能允许被间接访问
2. 当一个基,用派生类来构造它自己时,最后执行的函数,是基中的函数非派生类中的函数;同时,它也只能调用自己的函数,不能调用派生类中的函数
3. 派生类可以继承基类中的函数(即使没有在派生类中写出来);当写出来时,则派生类执行自己类内部的成员函数,不执行基类中的成员函数(非虚函数),但成员函数之间要求同名同形参
4. 当基类中的某个成员函数是虚函数时,则后面派生类中的同名成员函数可以有不同的形参
5. 总结:
a) 虚基,可以间接调用;
b) 虚函数,派生类的同名函数可以有不同形参(当然也可以不写出来默认使用基类中的)
上一篇: easyexcel 导入导出
下一篇: C++ 虚函数