class Student :public Person 学生是一个人,但是人不一定是学生
初始化列表中构造函数和缺省构造函数的使用
class Person {
private:
string _idPerson;
string _name;
int _age;
public:
Person() :_idPerson(), _name(), _age(1) {
cout << "Create Person" << this << endl;
}
Person(const string& id, const string name, const int age)
:_idPerson(id), _name(name), _age(age) {
cout << "Create Person(id,name,age)" << this << endl;
}
~Person() {
cout << "Destory Person" << this << endl;
}
void Eat()const {
cout << "吃饭" << this << endl;
}
void PrintInfo()const {
cout << "id:" << _idPerson << endl;
cout << "name:" << _name << endl;
cout << "age:" << _age << endl;
}
};
class Student :public Person {
private:
string _snum;
float _score;
public:
Student() :Person(), _snum(), _score(0) {
cout << "Create Student" << this << endl;
}
Student(const string& id, const string name, const int age,
const string& snum, const int score)
:Person(id, name, age), _snum(snum), _score(score) {
cout << "Create Student(id,name,age,snum,score)" << this << endl;
}
~Student() {
cout << "Destory Student" << this << endl;
}
void PrintStudent()const {
PrintInfo();
cout << "snum:" << _snum << endl;
cout << "score:" << _score << endl;
}
};
int main() {
Person per;
Student stu;
return 0;
}
int main() {
//Person per;
Student stu;
return 0;
}
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :public Object {
private:int bx;
protected:int by;
public:int bz;
};
int main() {
Object obj;
Base base;
return 0;
}
base对象模型,对于base
有四个成员,一个基类对象(没有名字的对象,用类型来标识,该基类对象成员有oa ob oc) ,自己的bx by bz,总共的大小为24byte
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :public Object {
private:int bx;
protected:int by;
public:int bz;
void func() {
bx = 0;by = 0; bz = 0;
oa = 0;//err 这是错的
ob = 0;
oc = 0;
}
};
int main() {
Object obj;
Base base;
return 0;
}
func是base的成员函数,可以访问base自己的公有 私有 保护 三个属性,而base 有一个继承而来的公有基类对象,他可以访问该继承而来的基类对象的公有数据成员,可以访问该继承而来的基类对象的保护数据成员,在继承关系中保护可以当公有使用,
但是不能访问继承而来对象的私有
当公有继承变成私有继承
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :private Object {
private:int bx;
protected:int by;
public:int bz;
void func() {
bx = 0;by = 0; bz = 0;
oa = 0;//err
ob = 0;
oc = 0;
}
};
int main() {
Object obj;
Base base;
return 0;
}
无论采用何种继承方式,派生类的成员方法都可以访问基类的公有和保护,不能访问基类的私有
func可以访问私有的bx,当然可以访问私有继承的基类,但是只能访问公有和保护,不能访问基类的私有
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :public Object {
private:int bx;
protected:int by;
public:int bz;
Object obj;
void func() {
bx = 0;by = 0; bz = 0;
obj.ob = 0;//err
obj.oc = 0;
}
};
int main() {
Object obj;
Base base;
base.func();
return 0;
}
继承的时候把保护的属性当做公有看待,对于成员来说公有就是公有,私有就是私有,保护就是保护,只能访问成员对象的公有属性,而无法访问成员对象的保护和私有
下面的访问都是可以的,base.Object::ob = 20;//err因为不是成员函数,不能访问,全局函数只能访问公有,这里如果是成员函数,就可以访问。
int main() {
Object obj;
Base base;
base.bz = 2;//该对象的公有属性
base.oc = 3;//该对象公有继承的公有属性
base.obj.oc = 4;//obj是该对象公有对象,而obj只能访问oc
base.Object::ob = 20;//err
}
成员方法可以访问自己类的公有 私有 保护,继承类的保护和公有,及成员对象的公有
而外部方法只能访问自己类的公有 ,继承类的公有,及公有成员对象的公有
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :public Object {
private:int bx;
protected:int by;
public:int bz;
Object obj;
void func() {
bx = 0;by = 0; bz = 0;
ob = 10; oc = 20;
obj.oc = 0;
//obj.ob=20;
}
};
int main() {
Object obj;
Base base;
base.bz = 2;
base.oc = 3;
base.obj.oc = 4;
//base.Object::ob = 20;//err
}
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :public Object {
private:int bx;
protected:int by;
public:int bz;
};
class Test :public Base {
private:
int ta;
protected:int tb;
public:int tc;
void func();
};
Test中的成员函数void func();,可以访问Test的公有私有保护,可以访问Base中的公有 保护,Object的公有保护
如果变成私有继承
class Object {
private:int oa;
protected:int ob;
public:int oc;
};
class Base :private Object {
private:int bx;
protected:int by;
public:int bz;
};
class Test :public Base {
private:
int ta;
protected:int tb;
public:int tc;
void func();
};
Test中的成员函数void func();,可以访问Test的公有私有保护,可以访问Base中的公有 保护,Object就不能访问,因为Base私有继承Object,这个不具名对象Object和int bx处于同等地位,func不能访问bx,所以func也不能访问Object.如果Base公有继承Object,这个不具名对象Object和int bz处于同等地位,func可以访问bz,则可以访问Object
采用就近原则,自己局部优先,隐藏基类的同名属性,如果想访问基类的属性,就要用类型名限定,
class Object {
public:
int sum;
int num;
};
class Base :public Object {
public:
void func() {
sum = 10;
Object::sum = 20;
}
int sum;
int value;
};
int main() {
Base base;
base.func();
base.sum = 20;
base.Object::sum = 30;
return 0;
}
这里不能看成函数的重载,函数的重载必须在同一个作用域下,这里是不同的作用域
class Object {
public:
void func(int x);
};
class Base :public Object {
public:
void func(int x,int y){}
};
int main() {
Base base;
base.func(2, 3);
//base.fun(2);//error
base.Object::func(1);
return 0;
}
可以用using声明一下,改变访问属性
class Object {
public:
void func(int x);
};
class Base :public Object {
public:
using Object::func;
void func(int x,int y){}
};
int main() {
Base base;
base.func(2, 3);
base.func(2);
base.Object::func(1);
return 0;
}
必须是公有继承只能把派生对象给基对象
,其中有切片现象
Person* p = & st;p指向派生对象的基对象
Person& re = st;st引用派生对象的基对象
class Person {private:string _id;};
class Student :public Person { string snum;};
int main() {
Person per;
Student st;
Person* p = &st;
Person& re = st;
per = st;
return 0;
}
注意有带参数构造就不会有缺省构造
调用不带参数的构造函数,当派生类没有明确调用基类哪个构造函数,会默认基类的默认构造函数或者缺省构造函数,所以基类没有默认构造函数或者缺省构造函数,程序将无法编译通过
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << this << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << this << endl;
}
~Person() { cout << "Destory Person " << this << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << this << endl;
}
~Student() { cout << "Destory Student " << this << endl; }
};
int main() {
Student s1;
return 0;
}
调用带参数的构造函数,没有明确调用基类的哪个构造函数,会调用默认构造函数或者缺省构造函数
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) : _sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,32008);
s1.PrintInfo();
return 0;
}
调用带参数的构造函数,明确调用基类的哪个构造函数
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,32008);
s1.PrintInfo();
return 0;
}
基类和派生类都没有拷贝构造,按照位拷贝,可以达到拷贝目的
派生类有拷贝构造函数,但是基类没有拷贝构造函数,Student(const Student& st) :_sid(st._sid) 这里会合成基类**缺省构造函数不是合成基类的默认拷贝构造(**合成不了),所以是0,所以将学生属性赋值,人的属性没有赋值
class Person {
private:
int _id;
public:
Person() :_id(0) {cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :_sid(st._sid) {
cout << "Copy Create Student " << endl;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
s1.PrintInfo();
Student s2 = Student(s1);
s2.PrintInfo();
return 0;
}
派生类和基类都有拷贝构造函数,在学生类拷贝构造里明确使用基类拷贝构造,就可以全部拷贝过来
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
s1.PrintInfo();
Student s2(s1);
s2.PrintInfo();
return 0;
}
基类有拷贝构造,派生类没有,基类要产生拷贝构造过程,编译器在编译的时候会给派生类型加上拷贝构造,以用来合成代码的时候调用基类的拷贝构造,这样也可以全部拷贝过来
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
//Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
// cout << "Copy Create Student " << endl;
//}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
s1.PrintInfo();
Student s2(s1);
s2.PrintInfo();
return 0;
}
基类和派生类都没有赋值语句,按照位赋值,可以达到目的
using namespace std;
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
//Student& operator=(const Student&st) {
// if (this != &st) {
// _sid = st._sid;
// }
// cout << "Student::operator= " << endl;
// return *this;
//}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
Student s2;
s1.PrintInfo();
s2.PrintInfo();
s2 = s1;
s1.PrintInfo();
s2.PrintInfo();
return 0;
}
基类和派生类都有赋值语句,但是在派生类没有明确告知调用基类哪个赋值语句,只能赋值下半截,基类属性无法赋值
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
Person& operator=(Person& pe) {
if (this != &pe) {
_id = pe._id;
}
cout << "Person::operator=() " << endl;
return *this;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
Student& operator=(const Student&st) {
if (this != &st) {
_sid = st._sid;
}
cout << "student::operator= " << endl;
return *this;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
Student s2;
s1.PrintInfo();
s2.PrintInfo();
s2 = s1;
s1.PrintInfo();
s2.PrintInfo();
return 0;
}
基类和派生类都有赋值语句,派生类明确告知调用基类哪个赋值语句,注意写法,就可以全部赋值过来
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
Person& operator=(const Person& pe) {
if (this != &pe) {
_id = pe._id;
}
cout << "Person::operator=() " << endl;
return *this;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
Student& operator=(const Student&st) {
if (this != &st) {
Person::operator=(st);
_sid = st._sid;
}
cout << "student::operator= " << endl;
return *this;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
Student s2;
s1.PrintInfo();
s2.PrintInfo();
s2 = s1;
s1.PrintInfo();
s2.PrintInfo();
return 0;
}
基类有赋值,派生类没有,基类要产生赋值语句过程,编译器在编译的时候会给派生类型加上赋值,以用来合成代码的时候调用基类的赋值语句,这样也可以全部拷贝过来
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
Person& operator=(const Person& pe) {
if (this != &pe) {
_id = pe._id;
}
cout << "Person::operator=() " << endl;
return *this;
}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
Student s2;
s1.PrintInfo();
s2.PrintInfo();
s2 = s1;
s1.PrintInfo();
s2.PrintInfo();
return 0;
}
基类没有赋值,派生类有,那么只能赋值学生的学号,人的身份证无法赋值
class Person {
private:
int _id;
public:
Person() :_id(0) { cout << "Create Person " << endl;
}
Person(int id):_id(id) {
cout << "Create Person(id) " << endl;
}
Person(const Person& pr) :_id(pr._id) {
cout <<"Copy Create person" << endl;
}
//Person& operator=(const Person& pe) {
// if (this != &pe) {
// _id = pe._id;
// }
// cout << "Person::operator=() " << endl;
// return *this;
//}
~Person() { cout << "Destory Person " << endl; }
void PrintPersonInfo()const { cout << "id:" << _id << endl; }
};
class Student :public Person {
private:
int _sid;
public:
Student() :_sid(0) {
cout << "Create Student " << endl;
}
Student(int id, int sd) :Person(id) ,_sid(sd) {
cout << "Create Student(id,sid)" << endl;
}
Student(const Student& st) :Person(st),_sid(st._sid) {//赋值兼容性 将学生给人的引用
cout << "Copy Create Student " << endl;
}
Student& operator=(const Student&st) {
if (this != &st) {
_sid = st._sid;
}
cout << "student::operator= " << endl;
return *this;
}
~Student() { cout << "Destory Student " << endl; }
void PrintInfo()const { PrintPersonInfo(); cout << "sid:" << _sid << endl; }
};
int main() {
Student s1(123,456);
Student s2;
s1.PrintInfo();
s2.PrintInfo();
s2 = s1;
s1.PrintInfo();
s2.PrintInfo();
return 0;
}
基类的静态成员,产生基类对象,该对象仍然只有一份,派生类共享同一个静态成员
基类的静态成员被所有派生类对象共享,也被基类对象共享
class Object {
private:int value;
protected:static int num;
public:
Object(int x=0):value(x){}
~Object(){}
};
int Object::num = 0;
class Base :private Object {
public:
Base() { cout << "Create Base : " << ++num << endl; }
~Base() { cout << "Destroy Base: " << --num << endl; }
};
class Test :public Object {
public:
Test() { cout << "Create Test: " << ++num << endl; }
~Test() { cout << "Destroy Test: " << --num << endl; }
};
int main() {
Test test[2];
Base base[3];
return 0;
}