概念
面向对象程序设计使代码复用的一种手段,是一种类设计层次的复用。
派生类
保持在原有类特性的基础上进行扩展,增加功能。
格式
class + 派生类 : 继承方式+基类--------> class Teacher : public Person
继承方式包括:public继承、provate继承、protexted继承。
class Person
{
public:
void Print()
{
cout << "name:" << _name << endl;
cout << "age:" << _age << endl;
}
protected:
string _name = "peter"; // 姓名
int _age = 18; // 年龄
};
//继承后父类的Person成员(包括成员变量与成员函数)都会变成子类的一部分。class Student:public Person
{
protect:
int _stuid;
};
class Teacher : public Person
{
peotect:
int _teaid;
};
int main()
{
Student s;
Teacher t;
s.Print();
t.Print();
return 0;
}
继承基类成员访问限定符的变化
- 基类private成员在派生类中无论以什么方式继承都是不可见的。在语法上限制派生类对象不管在类里还是类外都不能去访问;
- 基类private成员在派生类中不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected;
- 基类的私有成员在子类都是不可见的,基类的其他成员在子类的访问方式为public>protected>private;
- 关键字class默认的继承方式是private,struct默认的继承方式是public;
- provate与protected维护性不强,不提倡使用。
class Person
{
public:
void print()
{
cout << _name <<endl;
}
protected:
string _name;
private:
int _age;
};
class Student:public Person
{
protected:
int _stunum;
};
基类与派生类对象赋值转换
派生类对象可以赋值给基类的对象、基类的指针、基类的引用;
基类对象不能赋值给派生类对象;
基类的指针可以通过强制类型转化赋值给派生类的指针,但必须是基类的指针是指向派生类对象才是安全的。
class Person
{
protected:
string _name;
string _sex;
int _age;
};
class Student :public Person
{
public:
int _No;
};
void Test()
{
Student s;
//子类对象可以赋值给父类对象/指针/引用
Person p = s;
Person *pp = &s;
Person &p = s;
//基类可以强制类型转换赋值派生类
Student *ps=(Student* )pp;
}
集成中的作用域
- 在继承中基类与派生类有独立的作用域;
- 子类与父类中有同名成员,自类成员将屏蔽父类对同名成员的直接访问,这种叫隐藏,也叫重定义;
- 如果成员函数隐藏,只要函数名相同就就可以构成;
- 继承体内最好不要定义同名的成员。
class Person
{
protected:
string _name = "张三";
int _num = 11;
};
class Student:public Person
{
public;
void print()
{
cout << " 姓名" << _name << endl;
cout << "学号 " << Person::_num << endl;
cout << "年龄" <<_num << endl;
}
protected:
int _num = 111;
};
void test()
{
Student s;
s.print();
}
隐藏
class A
{
public:
void func()
{
cout << "func()" <<endl;
}
};
class B:public A
{
public:
void func(int i)
{
A::func();
cout << "func(int i) " << endl;
}
};
void test()
{
B b;
b.func(10);
}
派生类的默认成员函数
- 派生类的构造函数必须调用基类的构造函数初始化基类的一部分成员。
- 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
- 派生类的operator=必须调用基类的operator=完成基类的赋值。
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。保证先清理派生类对象再清理基类对象。
- 派生类对象初始化先调用基类构造再调用派生类对象。
- 派生类对象析构清理先调用派生类析构再调用基类的析构。
继承与友元、静态成员
友元不能被继承,基类成员不能访问子类的私有成员;整个体系只有这一个静态成员。