c++学习11、类和动态内存分配

string.h头文件

#ifndef STRING_H_

#include<iostream>
using std::ostream;
using std::istream;

#define STRING_H_

class String
{
private:
	char* str;
	int len;
	static int num_string;//静态类成员,对于所有类对象,该成员数据是共享的
public:
	static const int CINLIM = 80;
	String(const char* s);
	String();
	String(const String&);
	//复制构造函数和重载赋值运算符是不一样的东西
	~String();//在构造函数中使用new来分配内存时,必须在相应的析构函数中使用delete来释放该内存
	int length() const { return len; };
	String& operator=(const String&);
	String& operator=(const char*);
	char& operator[](int i);
	//利用重载后的下标运算符,可以像数组一样来访问什么位置的元素
	const char& operator[](int i) const;
	friend bool operator<(const String& st, const String& str2);
	friend bool operator>(const String& st1, const String& str2);
	friend bool operator==(const String& st, const String& st2);
	friend ostream& operator<<(ostream& os, const String& st);
	friend istream& operator>>(istream& is, const String& st);
	static int HowMany();
};

//在构造函数中使用new时应注意的事项:
//1、如果在构造函数中使用new,则应在析构函数中使用delete
//2、new和delete必须互相兼容
//3、如果有多个构造函数,则必须以相同的方式使用new,要么带[],要么什么都不带
//4、应定义一个复制构造函数,进行深度的复制
//5、应定义一个赋值运算符,进行深度的复制将一个对象复制给另一个对象

//返回引用一般是用来提高运行效率的一种,普通的返回会先生成一个临时变量,在进行赋值

//对象指针--可以将指针初始化为指向已有的对象

//在一下情况下会调用析构函数:1、对象是动态变量2、对象是静态变量3、new创建的要使用delete
#endif

string.cpp文件

#include<cstring>
#include"string1.h"
using std::cout;
using std::cin;

int String::num_string = 0;//初始静态类成员:指出类型,使用作用域解析运算符,不使用关键字static
//静态类成员不能在类声明,因为类声明不会分配内存,只是告诉如何分配内存,不能在同文件中声明,会在引入同文件时,生成多个版本
//注意只有枚举和const整数型,才可以在类声明中进行初始化

int String::HowMany()
{
	return num_string;
}

String::String(const char* s)
{
	len = std::strlen(s);
	str = new char[len + 1];
	std::strcpy(str, s);
	num_string++;
}

String::String()
{
	len = 4;
	str = new char[1];
	str[0] = '\0';
	num_string++;
}

String::String(const String& st)
{
	num_string++;
	len = st.len;
	str = new char[len + 1];
	std::strcpy(str, st.str);
}

String::~String()
{
	--num_string;
	delete[]str;
}

String& String::operator=(const String& st)
{
	if (this == &st)
		return *this;
	delete[]str;
	len = st.len;
	str = new char[len + 1];
	std::strcpy(str, st.str);
	return *this;
}

String& String::operator=(const char* s)
{
	delete[]str;
	len = std::strlen(s);
	str = new char[len + 1];
	std::strcpy(str, s);
	return *this;
}

char& String ::operator[](int i)
{
	return str[i];
}

const char& String::operator[](int i)const
{
	return str[i];
}

bool operator<(const String& st1, const String& st2)
{
	return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String& st1, const String& st2)
{
	return st2 < st1;
}

bool operator==(const String& st1, const String& st2)
{
	return (std::strcmp(st1.str, st2.str) == 0);
}

ostream& operator<<(ostream& os, const String& st)
{
	os << st.str;
	return os;
}

istream& operator>>(istream& is, String &st)
{
	char temp[String::CINLIM];
	is.get(temp, String::CINLIM);
	if (is)
		st = temp;
	while (is && is.get() != '\n')
		continue;
	return is;

}

类和动态内存分配.cpp文件

#include<iostream>
#include"string.h"

//通常最好是在程序运行时确定诸如使用多少内存等问题---oop式思想
//静态类成员有一个特点:无论创建多少个对象,程序都只创建一个静态类变量副本(只有一个)

//这里做一下总结5大特殊成员函数:默认构造函数、默认析构函数、复制构造函数、复制运算符、地址运算符
//在前面讲过只有一个参数的构造函数被用作转换函数
//如果没有提供这些函数,系统会在你要调用的时候自动生成该函数,但这些对于工作远远不够,还是要自己定义
/*如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这种被称作深度复制,成员复制或浅复制只是复制该内容的地址*/
//进行类中的赋值时,会先分配一个新的内存,如果地址不同,则要先把原来的地方释放掉

//以后要改掉习惯,要用nullptr来表示空指针,c是NULL

//静态类成员函数————只能访问静态数据成员-static,并且要使用类名+作用域解析运算符来进行调用

int main()
{

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值