初级C++:入门语法2.0


类的大小及空类

  • 一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

构造拷贝构造的优化

  • 当有临时对象产生时,构造拷贝构造连续发生,编译器会直接优化中间步骤1-》3
    在这里插入图片描述
    在这里插入图片描述

初始化列表、匿名对象、类型的销毁顺序

  • 匿名对象,生命周期旨在这一行A()

析构函数顺序分析

  • 栈帧压栈后进先出
  • 全局和静态的区别
  • 全局在main函数之前就初始化了
  • 静态是在 第一次调用域函数的时候 初始化
  • 先释放静态,再释放全局

初始化列表初始化,提高效率,可认为是成员变量初始化的地方,强制的有:引用 强制,自定义类型成员

  • 双向带头循环的例子证明声明的次序有关:
ListNode(int x)
		:val(x)
		, next(nullptr)
	{
		cout << "ListNode()" << endl;
	}

在这里插入图片描述


隐式类型转换、静态关键字详解

隐式类型转换

  • 内置类型转换成自定义类型,先用内置类型创建一个匿名对象,再用匿名对象拷贝构造给另一个对象,中间优化了。
  • C++11支持多个参数,explicit关键字可以阻止。
public:
 Date(int year)
 :_year(year)
 {}
 
 explicit Date(int year)
 :_year(year)
 {}
Date d1(2018);
d1 = 2019;/date(2019)->拷贝给临时变量,临时变量拷贝给形参
  • const int *p1; const修饰的是int,表示p1指向的变量值不可改变,指针本身可以改变.

静态static

  • 私有的静态变量,受到类域和访问限定符,更好体现封装,别人不能轻易修改
  • 提供一个共有的成员函数,利用匿名对象去调用;公有访问,类名::对象
  • 修饰全局变量或函数,改变的是链接接属性,旨在当前文件可见
  • 定义全局变量,明确调用了多少个构造对象

输入输出操作符及重载、友元函数及类

友元函数

  • 放在类里面的任何地方
  • 还可以定义友元类,单向的,A是B的友元类,B不能访问A,A可以B

cin、cout重载

  • 为了让cout在第一个参数,左左操作数,我们就只能写成全局的
  • 其次就是operator<<搞成友元,可以在类中访问私有。
  • 但是operator<<不是必须友元,还有其他方式,所以能不使用就不使用,因为破坏了封装。
friend ostream& operator<<(ostream& out, const Date& d);
friend istream& operator>>(istream& in, Date& d);

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day << endl;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

内部类

  • 在类的里面定义另外一个类,计算大小不考虑内部类
  • 受到A的类域的限制和访问限定符的限制,天生友元
  • 还可以访问外类的静态

New、Delete、内存布局

在这里插入图片描述

  • New是对operator new和构造函数的封装,是向系统申请。
  • new[]申请的是连续空间,同时会执行N次构造函数,new在申请空间失败时会抛异常。
  • new()是初始化
	try
	{
	char* p2 = new char[0x7fffffff]; / 出错,抛异常,调到捕获异常的位置
	}
	catch (const exception& e)
	{
	cout << e.what() << endl;
	}

delete

  • delete是对operator delete和析构函数的封装,delete[] 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理,下od同理。
  • operator new/ operator delete是两个全局函数,可实现向内存池申请和释放,提高效率。ONOD可以实现重载专属,可以记录一些信息。

placement-new

  • placement-new :在已分配的原始内存空间中调用构造函数初始化一个对象
    • 使用格式:new (place_address) type或者new (place_address) type(initializer-list)
    • place_address必须是一个指针,initializer-list是类型的初始化列表
    • 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,
    • 所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。
class Test
{
public:
 	Test()
	 : _data(0)
 {
	 cout<<"Test():"<<this<<endl;
 }
 ~Test()
 {
	 cout<<"~Test():"<<this<<endl;
 }
 
private:
 int _data;
};
// pt现在指向的只不过是与Test对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执
Test* pt = (Test*)malloc(sizeof(Test));
 // 如果Test类的构造函数有参数时,此处需要传参
 new(pt) Test


在堆上申请4G的内存

//建议改为x64位
#include <iostream>
using namespace std;
int main()
{
 void* p = new char[0xfffffffful];
 cout << "new:" << p << endl;
 return 0;
}

内存泄漏的危害和防止

  • 检测工具和智能指针
  • 危害:可能会被开除…阔怕啊
    在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值