C++继承 初始化列表 访问权限 同名隐藏 构造函数与拷贝构造的继承

继承

初始化列表

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;
}

在这里插入图片描述

多重继承

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值