//继承:是类设计层次的复用
#include
using namespace std;
//1、继承中的父子类 以及 父子类的赋值关系
// 基类/父类
class Person
{
public:
void Print()
{
cout<< "name:" << _name <<endl;
cout<< "age:" << _age <<endl;
}
protected:
string _name = "peter"; //姓名
int _age = 18; //年龄
};
// 子类/派生类
class Student : public Person
{
protected:
int _stuid; //学号
};
class Teacher : public Person
{
protected:
int _jobid; //工号
};
int main()
{
//Student s;
//s.Print(); //在类外面可以访问 public成员
//cout<< s._name <
double d = 1.1;
int i = d; //隐式类型的转化【中间会生成一个int类型的临时变量】
const int& ri = d; //【中间会生成一个int 类型的临时变量(具有常性)】
//父类对象无法赋值给子类对象(因为子类对象比父类对象大【子类对象不仅继承了父类的所有东西,还具有自己的东西】)
//子类对象可以赋值给父类对象(因为子类对象比父类对象大,可以将与父类对象共有的部分赋值给子类对象)
Student s;
Person p = s; //将子类对象中,与父类共有的部分赋值给父类对象.(天然支持的,不存在类型转换发生)
//(形象的说法是:切片/切割)
Person& rp = s; //给共有部分取别名为:rp
Person* ptrp = &s; //给共有部分取地址为:ptrp
return 0;
}
(1)父类和子类的同名成员变量
//在继承体系中,基类和派生类都有独立的作用域
//(1)父类和子类的同名成员变量
class Person
{
protected:
string _name = "小李子"; //姓名
int _num = 111; //身份证号
};
class Student : public Person
{
public:
void Print()
{
cout<< _num <<endl; //这里的 _num 为子类中的_num
cout<< Person::_num <<endl; //这里的 _num 为父类中的_num,需要标注出作用域
}
protected:
int _num = 999; //学号
// 子类和父类中有同名成员,子类成员将屏蔽对父类同名成员的直接访问,这种情况叫隐藏(重定义)。
// 建议在实际应用中,不定义同名成员。
};
int main()
{
Student s;
s.Print();
return 0;
}
(2)父类和子类的同名成员函数
//(2)父类和子类的同名成员函数
class A
{
public:
void func()
{
cout<< "func()" << endl;
}
};
class B : public A
{
public:
void func(int i)
{
A::func();
cout<< "func(int i)->" << i << endl;
}
};
void Test()
{
/*B b;
b.func(10);*/
//选择题:
// A 两个func构成函数重载 (构成函数重载的前提是:两个func需要在同一作用域内)
//选 B 两个func构成隐藏
// C 编译报错
// D 以上说法都不对
//
B b1;
b1.A::func();
}
int main()
{
Test();
return 0;
}
//3、子类的默认成员函数
class Person
{
public:
//构造函数
Person(const char* name = "peter")
:_name(name)
{
cout << "Person()" << endl;
}
//拷贝构造
Person(const Person& p)
:_name(p._name)
{
cout << "Person(const Person& p)" << endl;
}
//赋值
Person& operator=(const Person& p)
{
if (this != &p) //排除 自己给自己赋值的情况
_name = p._name;
cout << "Person& operator=(const Person& p)" << endl;
return *this;
}
//析构函数
~Person()
{
cout << "~Person()" << endl;
}
protected:
string _name; //姓名
};
class Student : public Person
{
public:
//构造函数
Student(const char* name, int num)
:Person(name)
//在继承体系的子类中,父类的成员变量必须由父类的构造函数去初始化
, _num(num)
{
cout << "Student()" << endl;
}
//拷贝构造
Student(const Student& s)
:Person(s)
, _num(s._num)
{
cout << "Student(const Student& s)" << endl;
}
//赋值
Student& operator=(const Student& s)
{
if (this != &s)
{
Person::operator=(s);
_num = s._num;
}
cout << "Student& operator=(const Student& s)" << endl;
return *this;
}
//在继承体系中,析构函数会被统一处理成 destructor
~Student()
{
//Person::~Person(); //不需要写
cout << "~Student()" << endl;
}
//子类析构函数完成时,会自动调用父类析构函数,保证先析构子再析构父
protected:
int _num; //学号
};
int main()
{
//Student s; //用子类实例化对象时,子类会自动调用父类的构造函数和析构函数
Student s1("张三", 18);
Student s2(s1);
// Person p = s1; //这儿调用的是 Person的拷贝构造
Student s3("JPC", 23);
s1 = s3;
return 0;
}