[C++]含指针的类的编写

//string.h

#ifndef __MYSTRING__
#define __MYSTRING__
#define _CRT_SECURE_NO_WARNINGS
class String
{
public:
	//默认构造函数,并设置默认值
	String(const char* cstr = 0);
 
	//Big Three三大函数:拷贝构造,拷贝赋值,析构。编译器会自动给出三大函数。
	//对于class with pointer,三大函数需要自己写,不能使用编译器给的默认版本。
	//不然会出现内存泄漏(memory leak)和别名(alias):多个指针指向同一块内存。
 
	//1. 拷贝构造
	String(const String& str);
	//2. 拷贝赋值,返回值为String&,可以满足连串赋值的操作
	String& operator=(const String& str);
	//3. 析构
	~String();
 
	char* get_c_str() const { return m_data; }
private:
	char* m_data;
};
 
#include <cstring>

inline
String::String(const char* cstr)
{
	//对传入的指针进行判断
	if (cstr) {
		m_data = new char[strlen(cstr) + 1];
		strcpy(m_data, cstr);
	}
	//若未指定初值
	else { 
		m_data = new char[1]; //为了搭配上面的写法
		*m_data = '\0';
	}
}
 
inline
String::~String()
{
	delete[] m_data;
}
 
inline
String& String::operator=(const String& str)
{
	//检查自我赋值(self assignment)
	//1. 提高效率
	//2. 正确性,如果自我赋值会出错
	if (this == &str)
		return *this;
 
	//经典写法1-2-3
	//1. 先清空自己指向的内存
	delete[] m_data;  
	//2. 分配需要的内存
	m_data = new char[strlen(str.m_data) + 1];
	//3. 最后拷贝数据
	strcpy(m_data, str.m_data);
	return *this;
}
 
//深拷贝,编译器自动给出的为浅拷贝
inline
String::String(const String& str)
{
	m_data = new char[strlen(str.m_data) + 1];
	strcpy(m_data, str.m_data);
}
 
#include <iostream>
using namespace std;
 
// <<的重载必须写为非成员函数
// 如果写成成员函数,使用者则需要这样写:string << cout; 这样不符合常用习惯。
ostream& operator<<(ostream& os, const String& str)
{
	os << str.get_c_str();
	return os;
}
 
#endif


//string-test.cpp

#include "string.h"
 
int main()
{
	String str1;
	String str2("hello str2");//默认构造
	String str3 = "hello str3";//默认构造
 
	String str4(str2);//拷贝构造
	String str5 = str4;//拷贝构造,同上
 
	str1 = str2;//赋值构造
 
	//重载<<
	cout << "str1:" << str1 << endl;
	cout << "str2:" << str2 << endl;
	cout << "str3:" << str3 << endl;
	cout << "str4:" << str4 << endl;
	cout << "str5:" << str5 << endl;
 
	//new:先分配memory,再调用ctor。
	String* pstr = new String[3];
	//编译器将上面语句翻译为下面三个动作
	//1. void* mem = operator new(sizeof(String)*3); 其内部调用malloc(n);
	//2. pc = static_cast<String*>(mem);
	//3. pc->String::String();调用三次构造
 
	pstr[0] = str1;
	pstr[1] = str2;
	pstr[2] = str3;
	cout << "pstr[1]:" << pstr[0] << endl;
	cout << "pstr[2]:" << pstr[1] << endl;
	cout << "pstr[3]:" << pstr[2] << endl;
 
	//delete:先调用dtor,再释放memory;
	delete[] pstr;
	//编译器将上面语句翻译为下面两个动作
	//1. String::~String(pstr);调用三次析构。
	//2. operator delete(pstr);  其内部调用free(pstr);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值