侯捷c++课程学习二

七、三大函数

拷贝构造、拷贝赋值、析构

1、string class(带指针)
class String
{
public:
	String(const char* cstr = 0); //构造,没有返回类型
	String(const String& str); //拷贝构造
	String& operator=(const String& str);//拷贝赋值,
//能否传回引用,看函数执行的结果放到什么地方去,放进去的地方是不是local object,
//只要不是就传reference,此处赋值目的端本来就存在,并不需要在函数operator=里创建,所以可以
	~String();
	char* get_c_str() const {return m_data;}//函数没有改动数据,所以加const
private:
	char* m_data; //放一个指针,32位系统中占4个字节
};

class里面有指针,多半要做动态分配,那么对象死亡之前,析构函数会被调用,释放动态分配的内存。


构造函数:

inline
String::String(const char* cstr = 0)
{
	if(cstr){ //传进来非空
		m_data = new char[strlen(cstr)+1]; //数组
		strcpy(m_data, cstr);
	}
	else{ //未指定初值,是空的,0
		m_data = new char[1];
		*m_data = '\0'; //把自己准备为一个空字符串,只有一个结束符
	}
}

inline //因为函数体简单,加上
String::~String(){
	delete[] m_data;
}
{
	String s1(),
	String s2("hello");
	
	String* p = new String("hello");
	delete p;
}
2、class with pointer members必须有copy构造和copy op=(assignment operator)

浅拷贝:两个指针指向同一块内存,易造成内存泄露(编程里别名是一个危险的事)
深拷贝:两个空间内容相同。拷贝构造函数,收到的参数就是自己的类型
拷贝构造函数:

inline
String::String(const String& str){
	m_data = new char[strlen(str.m_data)+1];
	strcpy(m_data, str.m_data);
}
3、copy assignment operator
inline
String& String::operator=(const String& str){
	if (this == &str) //检测自我赋值,如果是自身,那就不要做任何事,否则会出错
		return *this;
	
	delete[] m_data; //因为目的端本来就存在,先把原来内存清掉
	m_data = new char[strlen(str.m_data)+1]; //重新生成一块新的内存大小
	strcpy(m_data, str.m_data); //把数据赋过去
	return *this;//当有一连串赋值的时候要用//传出去的人不必知道接收端用什么接收
}

八、堆、栈与内存管理

1、Stack
存在于某作用域(scope)的一块内存空间(memory space),例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,返回地址,以及local object

  • c1即是栈对象,生命在大括号—作用域(scope)结束之际结束,又称auto object.
  • c2即静态对象,生命在作用域结束之后仍然存在,直到整个程序结束
  • 全局对象,生命在整个程序结束之后才结束
class Complex{..};
..
{
	Complex c1(1,2; //栈
	static Complex c2(1,2;
	Complex* p = new Complex(1,2); //堆,需自己手动delete
	..
	delete p;
}

2、Heap
操作系统提供的一块global内存空间,程序可动态分配若干区域

  • 不delete时出现内存泄露,因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p, 也就没机会delete p;
  • new: 先分配memory,再调用拷贝构造函数 pc->Complex::Complex(1,2); 谁调用谁就是那个this. Complex::Complex(pc,1,2) ,pc就是this

因为Complex类里面,数据只有实部、虚部两个private 的double类型,那么new出来的就是8字节大小的内存(一个double大小4个字节)

  • 复数里面没有指针,也不做动态分配
  • string类为一个指针,4个字节
  • delete: 先调用析构函数(一,把字符串里面的动态分配的那一块杀掉,清除指针指向的内存),再释放memory(二、把字符串本身(就是一个指针)清掉)
class String
{
public:
	~String(); //一
   {delete[] m_data;}
   ..
private:
	char* m_data; //二
};

array new一定搭配array delete.String *p = new String[3]; ... delete[] p;

九、复习string类的实现过程

十、扩展:类模板、函数模板及其他

1、static
静态函数只能处理静态数据

  • 单例模式,一旦有人用一次这个单例才会存在,并且永远只有这一个

2、cout
3、类模板
4、函数模板
编译器会做实参推导(argument deduction),将template< class T>中T自动转化为实际的类,但是类需要自己写好函数中需用到的操作符重载
5、namepace
将东西包在一个namespace里面

十一、组合和继承

1、Composition(复合),表示has-a
  • Adapter 设计模式
  • 成员变量、函数等
2、Delegation. Composition by reference(即使用指针传,也叫by reference)
  • 即两个类之间用指针相连,所以生命不同步,任何需要的时候创建,方便日后的更改,也方便共享

  • 包含一个指针指向为我实现所有功能的那一个类

3、Inheritance(复合),表示is-a

十二、虚函数与多态

十三、委托相关

原型prototype

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值