继承—— 菱形继承
定义:
两个派生类继承同一个基类,又有某个类同时继承者两个派生类。
class A
{
public:
A(int a)
{
_a = a;
}
int _a;
int funa()
{
cout << "A::funa()" << endl;
}
};
class B:virtual public A
{
public:
B(int a, int b)
:A(a)
{
_b = b;
}
int _b;
int funab()
{
cout << "B::funb()" << endl;
}
};
//虚继承
class C :virtual public A
{
public:
C(int a, int c)
:A(a)
{
_c = c;
}
int _c;
int func()
{
cout << "C::func()" << endl;
}
};
class D :public B, public C
{
public:
D(int a1, int a2, int b, int d, int c)
:A(10),B(a1, b), C(a2, c)
{
_d = d;
}
int _d;
int fund()
{
cout << "D::fund()" << endl;
}
};
int main()
{
D dd(1, 2, 3, 4, 5);
cout << dd._a << endl;
return 0;
}
查看布局:
- 自己写;
- 通过调试;
- cl /d1reportStringleClassLayoutD .\main.cpp >1.txt
菱形继承引入的问题:
- 造成公共父类在子对象中存在多个实例;
菱形继承的解决:
- 虚继承(虚基类)
虚继承的逻辑:
-
被虚继承的类会变成虚基类,虚基类在子类对象中存放在vbtable中,
-
原本应该存储该父类对象的位置上替换为vbptr,vbptr指向vbtable中虚基类实例的位置;
-
从而保证虚基类在子类中只会有一个实例的存在;
-
注意:虚基类在子类构造时会被当作直接父类进行构造。
抽象类
class A //抽象类
{
public:
virtual void fun() = 0;//纯虚函数
};
class AA :public A //如果不实现fun函数也是抽象类
{
public:
void fun1()
{
cout << "fun1()" << endl;
}
virtual void fun()
{
cout << "fun()" << endl;
}
};
- 有纯虚函数的类叫做抽象类;
- 抽象类不能够实例化对象;
- 要求限制子类必须覆盖某一个接口。
/完成学生系统的增删改查/
map表存储键值对;底层红黑树
enum TYPE
{
INSERT,
DELETE,
UPDATE,
SELECT
};
class View //抽象类
{
public:
virtual void process() = 0;
};
class View_insert :public View
{
public:
virtual void process()
{
cout << "insert" << endl;
}
};
class View_delete :public View
{
public:
virtual void process()
{
cout << "delete" << endl;
}
};
class View_update :public View
{
public:
virtual void process()
{
cout << "update" << endl;
}
};
class View_select :public View
{
public:
virtual void process()
{
cout << "select" << endl;
}
};
class Contral
{
public:
Contral()
{
_model.insert(make_pair(INSERT, new View_insert()));
_model.insert(make_pair(DELETE, new View_delete()));
_model.insert(make_pair(UPDATE, new View_update()));
_model.insert(make_pair(SELECT, new View_select()));
}
void process(int a)
{ //迭代器 // prosess时虚函数,产生动多态
map<int, View*>::iterator it = _model.find(a); // 父类指针指向子类对象
if (it != _model.end())
{
it->second->process(); //map first键 second值
}
}
private:
map<int, View*> _model;
};
int main()
{
Contral _c;
int a;
while (1)
{
cin >> a;
_c.process(a);
}
}
Contral Model View MVC框架——监听者模式