| 封装,继承和派生,多态 |
封装 (Encapsulation)是面向对象程序设计最基本的特性,把数据(属性)和函数(方法,操作)合成一个整体,这在计算机世界中是用类与对象实现的。
继承和派生:(继承和派生一体两面)
继承机制 是类型层次结构设计中实现代码的复用重要手段。
派生 是保持原有类特性的基础上进行扩展,增加新属性和新方法,从而产生新的类型。
在面向对象程序设计中,继承和派生是构造出新类型的过程,呈现类型设计的层次结构,体现了程序设计人员对现实世界由简单到复杂的认识过程。
const_cast static_cast (强制类型转化)层次概念是计算机的重要概念
C++通过类派生的机制来支持继承。被继承的类称为基类或父类,新产生的类称为派生类或子类。基类和派生类的集合称作类继承层次结构。
| 公有继承 | 保护继承 | 私有继承 | |
|---|---|---|---|
| 类中 | 公有和保护成员可以访问,私有成员不能访问 | 公有和保护成员可以访问,私有成员不能访问 | 公有和保护成员可以访问,私有成员不能访问 |
| 类外 | 公有成员可以访问,保护和私有成员不能访问 | 公有、保护和私有成员都不能访问 | 公有、保护和私有成员都不能访问 |
公有继承
私有成员在类内能被继承,不能被访问
保护和私有成员在类外不能被访问

保护继承
私有成员在类内不能被访问
公有、保护和私有成员在类外都不能被访问

私有继承
私有成员在类内不能被访问
公有、保护和私有成员在类外都不能被访问

继承是可以传递的
友元不能传递,也不能继承
在多层继承中,private可以将基类的东西私有化,其他派生类就不能使用


调用构造函数:
构造函数和析构函数不能被继承。我们知道构造函数和析构函数是跟对象的创建与消亡的剖作相关。我们所创建派生类的对象,虽然和基类的对象有相同之处,但是仍然是不同的对象。所用于基类的构造函数和析构函数不可能完全满足派生类对象的创建和消亡的善后工作。因此,构和析构函数不被继承。
其他函数都可以通过类对象来调用,创建对象时由系统调用该对象所属类的构造函娄该对象生存期中也只调用这一次。由继承而来的派生类对象,是能够调用父类的函数,但不能调函数也不能调用析构函数。
函数就是谁创建谁析构,如果继承下来的话会造成析构出现二义性,造成错误。
如果当前类中有指针作为数据成员,则程序中必须出现,析构函数,拷贝构造函数,赋值语句函数
基类的指针可以引用派生类对象,可以用派生类给基类赋值,但是基类不能给派生类赋值(不安全,多态,强制类型转化)
浅拷贝会造成内存泄漏

代码示例
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
class Person
{
public:
Person(const char* name = " ", const char sex = 'm', int age = 1)
:m_sex(sex), m_age(age)
{
m_name = new char[strlen(name) + 1];
strcpy(m_name, name);
}
~Person()
{
if (m_name != NULL)
{
delete []m_name;//必须添加中括号,否则会造成内存泄露
m_name = NULL;
}
}
Person(const Person& p) :m_sex(p.m_sex), m_age(p.m_age)
{
m_name = new char[strlen(p.m_name) + 1];
strcpy(m_name, p.m_name);
}
void Show()
{
cout << "name:" << m_name << endl;
cout << "age: " << m_age << endl;
cout << "sex: " << m_sex << endl;
}
private:
char* m_name;
char m_sex;
int m_age;
};
class Student :public Person
{
public:
Student(const char* name = " ", const char sex = 'm', int age = 1, const char* num = " ", float score = 80)
:Person(name, sex, age), m_score(score)
{
m_num = new char[strlen(num) + 1];
strcpy(m_num, num);
}
~Student()
{
if (m_num != NULL)
{
delete []m_num;
m_num = NULL;
}
}
Student(const Student& s) :Person(s), m_score(s.m_score)//传递对象
{
m_num = new char[strlen(s.m_num) + 1];
strcpy(m_num, s.m_num);
}
void Print()
{
Show();
cout << "num: " << m_num << endl;
cout << "score: " << m_score << endl;
}
private:
char* m_num;
float m_score;
};
class Teacher :public Person
{
public:
Teacher(const char* name = " ", const char sex = 'm', int age = 1, const char* course = " ", int money = 0)
: Person(name, sex, age),m_money(money)
{
m_course = new char[strlen(course) + 1];
strcpy(m_course, course);
}
~Teacher()
{
if (m_course != NULL)
{
delete[]m_course;
m_course = NULL;
}
}
Teacher(const Teacher& t) :Person(t), m_money(t.m_money)
{
m_course = new char[strlen(t.m_course) + 1];
strcpy(m_course, t.m_course);
}
void Print()
{
Show();
cout << "course: " << m_course << endl;
cout << "money: " << m_money << endl;
}
private:
char* m_course;
int m_money;
};
int main()
{
Student s("一", 'm', 20, "1001", 30);
s.Print();
Teacher t("二", 'f', 30, "语文", 3000);
t.Print();
Student ss;
ss.Print();
Teacher tt = t;
tt.Print();
return 0;
}
运行结果

函数指针实现
#include
int sum0(int);
int sum1(int);
int (*p[2])(int n) = { sum0,sum1 };//函数指针数组
int sum0(int n)
{
return 0;
}
int sum1(int n)
{
return p[!!n](n - 1) + n;//递归 !!n为1
}
int main()
{
printf("%d\n", sum1(100));
return 0;
}