C++基础学习笔记:类与动态内存分配

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gongjianbo1992/article/details/77931161

实现一个简单的string类

user.h

//!时间:2017年9月11日(周一)上午
//!内容:类与动态内存分配
//!备注:Test类实现简单的string功能
//!最后修改时间:NULL
//user.cpp
#define _CRTDBG_MAP_ALLOC//内存溢出检测
#include <iostream>
#include "Test.h"
using namespace std;
_CrtMemState s1, s2;//作为参数
int main()
{
	//如果程序从开始加flag这一句,leaks就能自动调用而不写
	//适合用在多个退出点的情况
	//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	//_CrtMemCheckpoint(&s1);//s1,s2之间可以具体定位
	//_CrtMemCheckpoint(&s2);
	{
		Test one = "this is test!";//构造
		Test two;//默认构造
		two = one;//赋值运算符Test
		two = "test two.";//赋值运算符char*
		Test three(one);//拷贝构造
		cin >> three;
		cout << one << two << three << endl;
	}//析构
	system("pause");
	_CrtDumpMemoryLeaks();//内存溢出检测
	return 0;
}

类定义

//Test.h
//#pragma once
#ifndef _TEST_H
#define _TEST_H
#include <iostream>

class Test
{
private:
	//C++11允许类内初始化
	char *cStr;
	static int count;//定义一个计数变量,监测内存的申请和释放次数
	const static int CINLIMIT=100;//cin>>字符串长度限制
public:
	Test(const char *s="");//构造函数:接受一个C字符串
	//拷贝与赋值需要逐个成员复制
	Test(const Test&t);//拷贝构造:Test two(one);
	Test&operator=(const Test&t);//赋值运算符:two=one;
	//若没有定义下面这一句,two="SOME"时,先把some通过构造函数隐式转换为Test,再调用上面那句
	Test&operator=(const char *s);//赋值运算符:two="some";
	void Show();//测试输出cStr与count;
	~Test();
	friend std::ostream&operator << (std::ostream &os, Test &t);//重载输入输出运算符
	friend std::istream&operator >> (std::istream &is, Test &t);
};
#endif
//Test.cpp
#include "Test.h"

int Test::count = 0;
Test::Test(const char *s)
{
	count++;
	//new匹配delete、new[]匹配delete[]
	cStr = new char[strlen(s) + 1];//申请一块字符串大小的内存
	strcpy_s(cStr, strlen(s) + 1, s);//拷贝内容
	//std::cout << "构造" << std::endl;
}
Test::Test(const Test&t)
{
	count++;
	cStr = new char[strlen(t.cStr) + 1];
	strcpy_s(cStr, strlen(t.cStr) + 1, t.cStr);
	//std::cout << "拷贝" << std::endl;
}
Test& Test::operator=(const Test&t)
{
	//std::cout << "赋值Test" << std::endl;
	if (this == &t)
		return *this;
	delete[]cStr;//释放旧的内存
	cStr = new char[strlen(t.cStr) + 1];//申请新的内存
	strcpy_s(cStr, strlen(t.cStr) + 1, t.cStr);
	return *this;//返回当前对象

}
Test& Test::operator=(const char *s)
{
	//std::cout << "赋值char*" << std::endl;
	delete[]cStr;//释放旧的内存
	cStr = new char[strlen(s) + 1];//申请新的内存
	strcpy_s(cStr, strlen(s) + 1, s);
	return *this;//返回当前对象
}
void Test::Show()
{
	std::cout << cStr <<":"<<count<< std::endl;
}
Test::~Test()
{
	delete[]cStr;//释放内存
	--count;
	std::cout << "当前count计数:" << count << std::endl;
}
std::ostream&operator << (std::ostream &os, Test &t)
{
	os << t.cStr;
	return os;
}
std::istream&operator >> (std::istream &is, Test &t)
{
	char temp[Test::CINLIMIT];
	is.get(temp, Test::CINLIMIT);
	if (is)//检测非法输入
		t = temp;//调用的赋值函数
	while (is&&is.get() != '\n')//清空流:没有到换行符,但还有大于CINLIMIT的输入
	{
		//std::cout << "++" << std::endl;
		continue;
	}
	return is;
}




猜你喜欢

转载自blog.csdn.net/gongjianbo1992/article/details/77931161