9.15日常记录

1.今日复习

104.二叉树最大深度,100.相同的树(判断条件有误),226.翻转二叉树,101.对称二叉树(满足的四个条件1.左右不为空且值不相等2.左右为空3.左不为空,右为空4.左为空。右不为空)

2.简单实现string类的一部分功能

string的构造函数实现了用于初始化string的对象,并且重载了<<操作符,目的是为了让它能够直接打印string类型的字符串,这里要注意,在os输出流当中,我的string类型对象是无法直接访问到string类中的私有成员的,需要将这个重载函数置为string类的友元类,才可以访问到string类的私有成员。

class String {
private:
	char* m_buffer;
	unsigned int m_size;//无符号整形代表大于零的整数
public:
	String(const char* string) {// 实现字符串拷贝
		m_buffer = new char[m_size + 1];
		m_size = strlen(string);
		memcpy(m_buffer,string,m_size+1);
	}
	friend std::ostream& operator<<(std::ostream& os, const String string);
};
std::ostream& operator<<(std::ostream& os,const String string) {
	os << string.m_buffer;
	return os;
}

int main() {
	String string = "Cherno";
	String second = string;
	//string[2] = 'a';
	std::cout << string << std::endl;
	std::cout << second << std::endl;
	//std::cin.get();
}

 此时的代码是有潜在问题的,如果说我设置了析构函数,在执行析构函数的时候会造成二次析构(报错如上所示),(浅拷贝),所以我们应该调整一下,因为默认的拷贝构造函数是浅拷贝,所以我们应该显示的定义一下拷贝构造函数,

String(const String& other) :m_size(other.m_size) {//实现深拷贝的代码
	m_buffer = new char[m_size + 1];
	memcpy(m_buffer,other.m_buffer,m_size+1);
}

 在运行的过程中,我一直崩溃,最后发现原来是因为构造函数中我是这么写的

	String(const char* string) {// 实现字符串拷贝
        m_buffer = new char[m_size + 1];
		m_size = strlen(string);
		memcpy(m_buffer,string,m_size+1);
		m_buffer[m_size] = 0;
	}

 而实际上在m_buffer执行时,m_size还没有被初始化,所以要注意执行的顺序,当我调换完位置之后就可以正常运行了。

 最后整体代码如下:

class String {
private:
	char* m_buffer;
	unsigned int m_size;//无符号整形代表大于零的整数
public:
	
	String(const char* string) {// 实现字符串拷贝
		m_size = strlen(string);
		m_buffer = new char[m_size + 1];
		memcpy(m_buffer,string,m_size+1);
		m_buffer[m_size] = 0;
	}
	//String(const String& other) :m_buffer(other.m_buffer), m_size(other.m_size) {//默认拷贝构造

	//}
	char&  operator[](unsigned int index) {
		return m_buffer[index];
	}
	~String() {
		delete[] m_buffer;
	}
	String(const String& other) :m_size(other.m_size) {//实现深拷贝的代码
		m_buffer = new char[m_size + 1];
		memcpy(m_buffer,other.m_buffer,m_size+1);
	}
	friend std::ostream& operator<<(std::ostream& os, const String& string);
};
std::ostream& operator<<(std::ostream& os,const String& string) {
	os << string.m_buffer;
	return os;
}

int main() {
	String string = "Cherno";
	String second = string;

	string[2] = 'a';

	std::cout << string << std::endl;
	std::cout << second << std::endl;
	std::cin.get();
}

 简单介绍一下易错点:

String string=“cherno”
这里的=并不是赋值运算符,是初始化,表明String类对象string隐式调用以“cherno”为唯一参数的构造函数,这种隐式调用特性可通过explicit(在对应构造函数前)关键字关闭
String string;string=“cherno”
这里的=才是赋值运算符,一是重载赋值运算符,接受字符串类型赋值给类。二是如果存在以“cherno”为唯一参数的构造函数,并且没有explicit(即允许隐式调用),编译器将隐式调用该构造函数生成一个临时String类对象,并用这个临时对象给string赋值,此时调用的是以String类为参数重载,可以自定义,如果没有自定义,编译器会自动生成,不过是浅拷贝

3.explicit关键字的作用

1.在修饰构造函数时,可以防止隐式转换和复制初始化

2.在修饰转换函数时,可以防止隐式转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值