C++基础13-类和对象之继承2

总结:

1、子类对象可以当做父类对象使用
2、子类对象可以直接赋值给父类对象
3、子类对象能够直接初始化父类对象
4、父类指针可以直接指向子类对象
5、凡是继承过来的属性和函数都可以在子类中用this->  进行访问
6、默认构造函数并不会初始化数据成员
7、如果子类数据成员和父类数据成员名称相同。在子类用利用:: 访问父类数据成员,this-> 默认为子类数据成员

8、构造函数和析构函数不会被继承

一、类型兼容性规则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。

类型兼容规则中所指的替代包括以下情况:

             <1>子类对象可以当作父类对象使用

             <2>子类对象可以直接赋值给父类对象

             <3>子类对象可以直接初始化父类对象

             <4>父类指针可以直接指向子类对象

             <5>父类引用可以直接引用子类对象

继承模型:

在子类对象构造时,需要调用父类构造函数对其继承得来的成员进行初始化.

在子类对象析构时,需要调用父类析构函数对其继承得来的成员进行清理.

二、继承中构造析构调用原则

        1、子类对象在创建时会首先调用父类的构造函数

        2、父类构造函数执行结束后,执行子类的构造函数

        3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用

        4、析构函数调用的先后顺序与构造函数相反

总原则:

                      先构造父类,再构造成员变量、最后构造自己

                      先析构自己,在析构成员变量、最后析构父类

三、继承中同名成员变量处理方法

1、当子类成员变量与父类成员变量同名时 ,子类依然从父类继承同名成员

2、在子类中通过作用域分辨符::进行同名成员区分(在派生类中使用基类的同名成员,显式地使用类名限定符)

注:同名成员存储在内存中的不同位置

四、派生类中的static关键字

1、基类定义的静态成员,将被所有派生类共享

2、根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质 (遵守派生类的访问控制)

3、 派生类中访问静态成员,用以下形式显式说明:

                                      类名 :: 成员

       或通过对象访问      对象名 . 成员

示例:

1、类的兼容性规则

#if 1
#include<iostream>
using namespace std;

class Parent {
public:
	void printP() {
		cout << "a:" << this->a << endl;
	}
	int a;
};
class Child :public Parent {
public:
	/*void printP() {
		cout << "b:" << this->b << endl;
	}*/
	void printC() {
		cout << "b:" << this->b << endl;
	}
	int b;
};
void test01() {
	Parent *p = new Child;
	p->printP();  //子类和父类都有printP函数时,调用父类的成员函数
}
//子类对象可以当做父类对象使用
//子类对象可以直接赋值给父类对象
//子类对象能够直接初始化父类对象
void test02() {

	Parent p;  //父类空间小
	//Child c = p; //子类空间大于父类,不能够全部初始化,所以报错

	Child c;
	Parent p = c;  //c对象占用空间>=p对象占用空间 
				   //能够填充可以通过编译
				   //子类对象能够直接初始化父类对象

	c.printP();  //c能够当做父类p来使用

}
//父类指针可以直接指向子类对象
//好处:
void test03() {
	Parent *pp = NULL;  //父类指针
	Child *cp = NULL;   //子类指针
	Parent p;  //父类对象
	Child c;   //子类对象

	cp = &c;
	//cp = &p;  子类指针指向父类对象 错误 子类指针访问范围大于父类对象的范围
	            //原来cp的访问权限为cp->a,cp->b,cp->printP.cp->printC
				//cp指向p时,cp的访问权限只能为cp->a,cp->printP
				//会访问越界
	pp = &p;
	pp = &c;  //通过编译 父类指针指向子类对象
		      //原来cp的访问权限为pp->a; pp->printP
			  //pp指向c时,cp的访问权限扔为pp->a; pp->printP
			  //c内存布局能够满足父类指针的全部需求  可以用一个儿子的对象地址给父类指针赋值
	          
}
int main() {
	
	return 0;
}
#endif

2、构造函数和析构函数

#if 0
#include<iostream>
using namespace std;
//在调用子类的构造函数时  一定会调用父类的构造函数
//父类先构造,子类再构造
//析构和构造顺序相反
class Parent {
public:
	Parent() {
		cout << "Parent()... " << endl;
		a = 0;
	}
	Parent(int a) {
		cout << "Parent(int a)..." << endl;
		this->a = a;
	}
	int a;
	~Parent() {
		cout << "~Parent()..." << endl;
	}
};
class Child :public Parent {
public:
	//在调用子类的构造函数时  编译器会默认调用父类无参构造
#if 0
	Child(int a,int b) 
	{
		cout << "Child(int a,int b)..." << endl;
		this->a = a;
		this->b = b;
	}
#endif
	//显示调用父类有参构造
	Child(int a ,int b):Parent(a)
	{
		cout << "Child(int a,int b)..." << endl;
		this->b = b;
	}
	~Child() {
		cout << "~Child()... " << endl;
	}
	void printC() {
		cout << "b=" << b << endl;
	}
	int b;
};

//在调用子类时 编译器会默认调用父类无参构造 
void test01() {
	Child c(10, 20);
	c.printC();
}
/*
Parent()...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
//显示调用父类有参构造
void test02() {
	Child c(10, 20);
	c.printC();
}
/*
Parent(int a)...
Child(int a,int b)...
b=20
~Child()...
~Parent()...
*/
int main() {
	test01();
	return 0;
}
#endif

3、子类和父类成员重名

#if 0
#include<iostream>
using namespace std;
#if 0
class Parent {
public:
	Parent() {
		cout << "Parent() " << endl;
		this->a = 0;
	}
	Parent(int a) {
		cout << "Parent(int a) " << endl;
		this->a = a;
	}
	~Parent() {
		cout << "析构父类a:" << this->a << endl;
	}
	int a;
};
class Child :public Parent {
public:
	int a;
	Child(int a) {
		cout << "Child(int a)" << endl;
		this->a = a;
	}
	~Child() {
		cout << "析构子类a:" << this->a << endl;
	}
};

void test01() {
	Child c(2);
}
/*
Parent()
Child(int a)
析构子类a:2
析构父类a:0
*/
#endif
#if 0
class Parent {
public:
	Parent(int a) {
		cout << "Parent(int a) " << endl;
		this->a = a;
	}
	~Parent() {
		cout << "析构父类a:" << this->a << endl;
	}
	int a;
};
class Child :public Parent {
public:
	int a;
	Child(int p_a,int c_a):Parent(p_a){
		cout << "Child(int a)" << endl;
		this->a = c_a;
	}
	~Child() {
		cout << "析构子类a:" << this->a << endl;
	}
	void print() {
		cout << "父类a:"<<Parent::a << endl;
		cout <<"子类a:" <<this->a << endl;  //子类的a
	}
};

void test01() {
	Child c(2,3);
	c.print();
}
/*
Parent(int a)
Child(int a)
父类a:2
子类a:3
析构子类a:3
析构父类a:2
*/
#endif
//子类和父类函数名相同调用 
class Parent {
public:
	Parent(int a) {
		cout << "Parent(int a) " << endl;
		this->a = a;
	}
	void print() {
		cout << "父类print" <<  endl;
	}
	~Parent() {
		cout << "析构父类a:" << this->a << endl;
	}
	int a;
};
class Child :public Parent {
public:
	int a;
	Child(int p_a, int c_a) :Parent(p_a) {
		cout << "Child(int a)" << endl;
		this->a = c_a;
	}
	~Child() {
		cout << "析构子类a:" << this->a << endl;
	}
	void print() {
		cout << "子类print" << endl;  //子类的a
	}
};

void test01() {
	Parent p(1);
	p.print();
	cout << "------" << endl;
	Child c(2, 3);
	c.Parent::print();
	c.print();	
}
/*
Parent(int a)
父类print
------
Parent(int a)
Child(int a)
父类print
子类print
析构子类a:3
析构父类a:2
析构父类a:1
*/
int main() {
	test01();
	return 0;
}
#endif

4、继承中的static成员

#if 1
#include<iostream>
using namespace std;
#if 0
class A {
public:
	static int a;
private:
};
int A::a = 0;  //静态成员变量 初始化

void test01()
{
	A a1;
	A a2;
	cout << a1.a << endl;
	cout << a2.a << endl;
	a1.a = 300;
	cout << a1.a << endl;
	cout << a2.a << endl;
}
/*
0
0
300
300
*/
#endif

class A {
public:
	static int a;
private:
};
class B :public A {
public:
private:
};
int A::a = 0;  //静态成员变量 初始化

void test01()
{
	A a1;
	A a2;
	cout << a1.a << endl;
	cout << a2.a << endl;
	a1.a = 300;
	cout << a1.a << endl;
	cout << a2.a << endl;

	B b1;
	B b2;
	cout << b1.a << endl;
	cout << b2.a << endl;
	A::a = 400;
	cout << b1.a << endl;
	cout << b2.a << endl;
}
/*
0
0
300
300
300
300
400
400
*/
int main() {
	test01();
	return 0;
}
#endif

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chde2Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值