c++入门笔记 从对象到纯虚构造

对象的初始化分类

c++

拷贝构造函数

1.使用一个已经创建完毕得对象来初始化一个新对象

2.值传递得方式给函数参数传值

3.以值方式返回局部对象

构造函数调用规则

1.默认构造函数(无参。函数体空)

2.默认析构函数(无参。函数体空)

3.默认拷贝构造函数,对属性进行拷贝

深拷贝 浅拷贝

1.浅拷贝带来得问题就是堆区得内存重复释放

2.浅拷贝得问题要利用深拷贝进行解决。

总结:如果属性有在堆区开辟得,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题。

class Person
{
public:
	Person()
	{
		cout << "默认构造函数调用" << endl;
	}
	Person(int age,int height)
	{
		m_Age = age;
		m_Height=new int(height);
		cout << "有参默认构造函数调用" << endl;
	}
	Person(const Person& p)
	{
		cout << "拷贝构造函数" << endl;
		m_Age = p.m_Age;
		//深拷贝
		m_Height=new int(*p.m_Height);
	}
	~Person()
	{
		cout << "析构函数调用" << endl;
	}
	int m_Age;//年龄
	int* m_Height;
};
void test01()
{
	Person p1(18 ,160);
	cout <<  p1.m_Age <<"   "<< *p1.m_Height<<endl;
	Person p2(p1);
	cout << p2.m_Age << endl;
}
int main()
{
	 

	test01();
	system("pause");
	return 0;

}


类对象作为类成员

class Phone
{
public:
	Phone(string name)
	{
		m_PhoneName = name;
		cout << "苹果构造" << endl;
	}
	~Phone()
	{
		cout << "手机xigo" << endl;
	}
	string m_PhoneName;
};

class Person
{
public:
	Person(string name, string pName) :m_Name(name),m_Phone(pName)
	{

	}
	string m_Name;
	Phone m_Phone;
	~Person()
	{
		cout << "调用" << endl;
	}
	void playGame()
	{
		cout << m_Name << "拿着:" <<m_Phone.m_PhoneName << endl;
	}

};
void test01()
{
	Person p("sb", "苹果");
	p.playGame();
}
int main()
{
	test01();

	system("pause");
	return 0;

}

静态成员

关键字 static

类外访问不到类内的静态成员函数

成员变量和成员函数分开存储

空对象占用内存空间为1;

c++编译器会给空对象分配一个字节空间,为了区分空对象占内存位置。即有独一无二地址

非静态成员变量属于类的对象上

静态成员变量不属于类的对象上

this指针的使用

this指针指向被调用的成员函数所属的对象

this->age= age;

1.解决名称冲突

2.返回对象本身用*this

(this指向P2的指针,而*this指向的就是p2这个对象本体)

空指针调用成员函数

健壮性

const修饰成员函数

const不可以修改成员属性

关键字mutable就可以 修改。

常对象只能调用常函数

在对象前加const就是常对象

mutable在常函数和常对象内都可以修改

友元

友元关键字 friend

友元的三种实现

1.全局函数做友元

2.类做友元

3.成员函数做友元

告诉编译器

friend+函数体

类做友元

友元函数可以访问本类中的私有成员

成员函数做友元

friend

运算符重载

1.加号运算符重载

2.左移动运算符重载

ostream &operator(ostream &cout,Person&p)

{

out<<xxxxxx

return out;

}

3.递增运算符重载

4.赋值运算符重载

继承

继承的好处就是减少重复的代码

class A: public B

A类成为子类 或派生类

B类成为父类或基类

派生类中的成员,包含两大部分

一类是从基类继承过来的,一类是自己增加的成员

从基类继承过来的表现性共性,新增的成员体现了其个性

继承的方式

语法: class 子类:继承 父类

继承的方式

1.公共继承

2.保护继承

3.私有继承

继承中的对象模型

在父类中所有非静态成员属性都会被子类继承下去

父类中私有成员属性被编译器隐藏,但是有继承的行为

利用开发人员命令提示工具查看对象模型

跳转符 F:

跳转文件路径 cd 具体路径

查看命名

c1 / d1 reportSingClassLayout类名

继承中构造和析构顺序

继承中的构造和析构顺序如下

先构造父类,再构造子类,析构的顺序和构造相反。.

继承同名成员处理方式

子类对象可以直接访问到子类中同名成员

子类对象加作用域可以访问父类同名成员

当子类和父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

x.父类::函数

继承同名静态成员处理方式

与上面一样

多继承语法

class 子类: 继承方式 父类1,继承方式 父类2…

菱形继承

利用虚继承 解决菱形继承的问题

在继承之前加上关键字virtual 变为虚继承

vbptr —vbtable

v-virtual

b-base

ptr-pointer

多态

多态基本概念

多态分为

静态多态:函数重载,运算符重载,复用函数名

动态多态: 派生类和虚函数是实现运行时多态

静态多态和动态多态区别

静态多态的函数地址早绑定-编译阶段确定函数地址

动态多态的函数地址晚绑定-运行阶段确定函数地址

虚函数virtual

动态多态满足条件

1.有继承条件

2.子类要重写父类的虚函数 重写 函数返回值类型 函数名 参数列表 相同

动态多态使用

父类的指针或者引用 执行子类对象

多态原理剖析

指针4个字节

当子类重写父类的虚函数

子类中的虚函数表内部会替换成子类的虚函数地址

当父类的指针或者引用指向子类对象时候,发生多态

Animal & animal=cat;

animal.speak();

多态的案例

多态的优点

代码清晰

可读性强

利于前期后期的拓展以及维护

纯虚函数和抽象类

在多态中,通常父类中虚函数的实现没有意义主要是调用子类重写内容 所以可以改为纯虚函数

纯虚函数 virtual 返回值类型 函数名 (参数列表)=0;

当类中有纯虚函数,这个类也成为抽象类

抽象类特点

无法实例化对象

子类必须重写抽象类中的虚函数,否则也属于抽象类

虚析构和纯虚构

多态使用时候,如果子类中属性开辟到堆区,那么父类指针在释放的时候无法调用子类的析构代码

解决办法:将父类中的析构函数改为虚析构或者纯虚构

虚析构和纯虚构共性

可以解决父类指针释放子类对象

都需要有具体的函数实现

虚析构和纯虚构区别

如果是纯虚构,该类是抽象类 无法实例化。

虚析构 virtual ~类名(){}

纯虚构 virtual~类名()=0;

类名::

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值