前言
这部分一直以来都是C++基础的重点,这阵子正好在学,记录一下。上课听的时候发现老师其实讲的有点模糊,涉及到的方面也比较多。
继承
#include <iostream>
#include <stdlib.h>
using namespace std;
class Person
{
public:
virtual void BuyTicket()
{
cout << "买票-全价" << endl;
}
Person(){
cout << "父类构造函数" << endl;
}
virtual ~Person(){
cout << "fuleixgou" << endl;
}
};
class Student : public Person
{
public:
virtual void BuyTicket(){
cout << "买票-半价" << endl;
}
Student(){
cout << "子类构造函数" << endl;
}
virtual ~Student(){
cout << "zileixgou" << endl;
}
};
void Func(Person& p)
{
p.BuyTicket();
}
int main()
{
Person ps;
Student st;
Func(ps);
Func(st);
return 0;
}
运行结果:
父类构造函数
父类构造函数
子类构造函数
买票-全价
买票-半价
zileixgou
fuleixgou
fuleixgou
--------------------------------
Process exited after 0.2538 seconds with return value 0
请按任意键继续. . .
这个应该没有什么问题,但是这里引出一个虚继承!
虚继承
看这篇文章,看完应该就可以了解继承和虚继承的整个内存布局了。
多继承
看一下这个例子:
#include <iostream>
using namespace std;
class A {
int data0;
public:
A() {
cout << "A gouzao" << endl;
}
};
class B : public A {
int data1;
public:
B() {
cout << "B gouzao" << endl;
}
};
class C : public A {
int data2;
public:
C() {
cout << "C gouzao0" << endl;
}
};
class D : public B, public C {
int data3;
public:
D() {
cout << "D gouzao" << endl;
}
};
int main() {
D d;
int a;
cin >> a;
return 0;
}
运行:
A gouzao
B gouzao
A gouzao
C gouzao0
D gouzao
下面这个对比一下上面那个:
#include <iostream>
using namespace std;
class A {
int data0;
public:
A() {
cout << "A gouzao" << endl;
}
};
class B : virtual public A {
int data1;
public:
B() {
cout << "B gouzao" << endl;
}
};
class C : virtual public A {
int data2;
public:
C() {
cout << "C gouzao0" << endl;
}
};
class D : public B, public C {
int data3;
public:
D() {
cout << "D gouzao" << endl;
}
};
int main() {
D d;
return 0;
}
运行结果:
A gouzao
B gouzao
C gouzao0
D gouzao
--------------------------------
Process exited after 0.3061 seconds with return value 0
请按任意键继续. . .
可以看到区别还是挺大的,大家自行体会一下,同时结合上面关于虚继承的内存分布文章。
多继承虚函数
关于这个部分也有一篇文章,大家可以看一下。
看一下这个例子:
#include <iostream>
using namespace std;
class A {
public:
void virtual f() {
cout << "A:f" << endl;
}
void virtual g() {
cout << "A:g" << endl;
}
void virtual h() {
cout << "A:h" << endl;
}
};
class B : public A {
public:
void f() {
cout << "B:f" << endl;
}
void virtual g1() {
cout << "B:g" << endl;
}
void virtual h1() {
cout << "B:h" << endl;
}
};
int main() {
A *a;
B b;
a = &b;
a->f();
b.f();
return 0;
}
运行:
B:f
B:f
--------------------------------
Process exited after 0.2939 seconds with return value 0
请按任意键继续. . .
可以看到,派生类要是有跟父类同样的函数名是会覆盖掉父类的,那么如何调用到父类的函数呢?应该是要直接创建父类的实例吧?(应该是的)
再看一个实例:
#include <iostream>
using namespace std;
class A {
public:
void virtual f() {
cout << "A:f" << endl;
}
void virtual g() {
cout << "A:g" << endl;
}
void virtual h() {
cout << "A:h" << endl;
}
};
class B {
public:
void virtual f() {
cout << "B:f" << endl;
}
void virtual g() {
cout << "B:g" << endl;
}
void virtual h() {
cout << "B:h" << endl;
}
};
class C {
public:
void virtual f() {
cout << "C:f" << endl;
}
void virtual g() {
cout << "C:g" << endl;
}
void virtual h() {
cout << "C:h" << endl;
}
};
class D :public A,public B, public C{
public:
void f1() {
cout << "D:f1" << endl;
}
void h1() {
cout << "D:h1" << endl;
}
};
int main() {
D d;
A *a = &d;
a->f();
int c;
cin >> c;
return 0;
}
运行:
A:f
当main函数中是这样的话:
D d;
d.f();
这样是编译不通过的,因为f函数指示不明确。
关于虚指针和虚表,额这个在上面两篇文章之中应该已经有很好的体现了。
关于C++的内存模型,这个还是比较重要的,可以跟虚表一起结合,对一个程序有一个比较宏观的看待。
---------------------------未完待续---------------------------------------