版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}