首页 > 编程语言 > 详细

【C/C++】【类和对象】基类和派生类

时间:2020-07-21 12:03:19      阅读:66      评论:0      收藏:0      [点我收藏+]

派生类对象模型

子类对象包含多个组成部分(也就是多个子对象);

  1. 含有派生类自己定义的成员变量、成员函数的子对象;
  2. 该派生类所继承的基类的子对象,这个子对象包含的是基类中定义的成员变量、成员函数(派生类对象含有基类对应的组成部分);
  • 两部分数据在内存中的存储可能不连续;
  • 基类指针可以new派生类对象,因为派生类对象含有基类部分,所以我们可以把派生类对象当成基类对象来用;编译器内部做了隐式的派生类到基类的转换;这种转换的好处是有些需要用到基类引用/指针地方,可以用这个派生类对象的引用/指针来代替;

派生类构造函数

  • 派生类实际使用基类的构造函数来初始化它的基类部分;基类控制基类部分的成员初始化,派生类控制派生类部分成员的初始化;
  • 定义一个派生类对象的时候,既调用基类构造函数,有调用派生类构造函数;
  • 传递参数给基类构造函数问题:通过派生类的构造函数初始化列表;
#include <iostream>
using namespace std;
class Father
{
public:
	Father(int i):m_values(i)
	{
		cout << "Father(int i)" << endl;
	}
	virtual ~Father()
	{
		cout << "~Father()" << endl;
	}
private:
	int m_values;
};
class Son : public Father
{
public:
	//通过子类的初始化列表给父类构造函数传参
	Son(int i, int k):Father(i), m_value_b(k)
	{
		cout << "Son(int i, int k)" << endl;
	}
	~Son()
	{
		cout << "~Son()" << endl;
	}
public:
	int m_value_b;
};
int main()
{
	//构造函数:先基类再子类
	//析构函数:先子类再基类
	Son* b = new Son(1, 2);
	delete b;

	return 0;
}

既当父类又当子类

  1. Base
  2. Father: Base是Father的直接基类
  3. Son:Base是Sone的间接基类
    继承关系一直传递,构成了一种继承链,最终的结果是Son会包含它的直接基类的成员以及每个间接基类的成员
    Father这个类就是既当父类又当子类;
#include <iostream>
using namespace std;
class Base
{
public:
	Base() 
	{
		cout << "Base()" << endl;
	};
	~Base() 
	{
		cout << "~Base()" << endl;
	};
};
class Father: public Base
{
public:
	Father(int i):m_values(i)
	{
		cout << "Father(int i)" << endl;
	}
	virtual ~Father()
	{
		cout << "~Father()" << endl;
	}
private:
	int m_values;
};
class Son : public Father
{
public:
	//通过子类的初始化列表给父类构造函数传参
	Son(int i, int k):Father(i), m_value_b(k)
	{
		cout << "Son(int i, int k)" << endl;
	}
	~Son()
	{
		cout << "~Son()" << endl;
	}
public:
	int m_value_b;
};

int main()
{
	Son* son = new Son(1, 2);
	delete son;
	return 0;
}

不想当基类的类

final:C++11中引入,加到基类后面,使其无法被继承;

class Base final
{
public:
	Base() 
	{
		cout << "Base()" << endl;
	};
	~Base() 
	{
		cout << "~Base()" << endl;
	};
};
class Father
//class Father : public Base 错误
{
public:
	Father(int i):m_values(i)
	{
		cout << "Father(int i)" << endl;
	}
	virtual ~Father()
	{
		cout << "~Father()" << endl;
	}
private:
	int m_values;
};

静态类型和动态类型

  • 静态类型:变量声明的时候的类型,静态类型编译的时候类型是已知的;
  • 动态类型:这个指针/引用所代表的的内存中的对象的类型;运行的时候才知道类型;
  • 动态类型和静态类型;只有基类指针/引用才存在静态类型和动态类型不一致的情况;如果不是基类指针/引用,其动态类型和静态类型永远是一致的;

派生类向基类的隐式类型转换

基类对象能独立存在,也能作为派生类对象的一部分存在

Father* father = new Son(); //积累指针指向一个派生类对象	
Father& q = *father;	//基类引用绑定到派生类对象
Son son;
Father* father = &son; //可以
Son* p_son = father; // 非法,编译器通过静态类型推断转换合法性,发现基类不能转成派生类;如果基类中有虚函数,可以通过dynamic_cast转换;
Son* p_son = dynamic_cast<Son*> father;

并不存在从基类到派生类的自动类型转换

Son* son = new Father(); //非法		

Father father;
Son &son = father; //非法,不能将基类转换成派生类,派生类的引用不能绑定到基类对象上
Son &son = &father; //非法,不能讲基类转成派生类,派生类指针不能指向基类地址

父类子类之间的拷贝和赋值

用派生类对象为一个基类对象初始化或者赋值的时候,只有该派生类对象的基类部分会被拷贝或者复制,派生类部分将被忽略掉;

Son son; //派生类对象;
Father father(son); //用派生类对象来定义并初始化基类对象,这个会导致基类的拷贝构造函数的执行

【C/C++】【类和对象】基类和派生类

原文:https://www.cnblogs.com/Trevo/p/13343854.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!