注意,在VS2017环境下,不能直接使用C函数strcpy, 这里使用strcpy_s,另外使用inline关键字会报错,这里也不使用
MyString.h
#pragma once
#include <iostream>
class MyString
{
public:
MyString(const char* cstr = 0);
MyString(const MyString& str);
MyString& operator=(const MyString & str);
~MyString();
char* get_c_str() const { return m_data; }
private:
char* m_data;
};
std::ostream& operator<<(std::ostream& os, const MyString &str);
MyString.cpp
#include "MyString.h"
#include <iostream>
MyString::MyString(const char* cstr)
{
// 思考这里为什么不用先删除m_data
// 因为构造函数创造对象是m_data一定为空
if (cstr) {
m_data = new char[strlen(cstr) + 1];
strcpy_s(m_data, strlen(cstr) + 1, cstr);
}
else {
m_data = new char[1];
*m_data = '\0';
}
}
MyString::~MyString()
{
delete[] m_data;
}
MyString::MyString(const MyString& str)
{
// 思考这里为什么不用先删除m_data
// 拷贝构造创建对象时,m_data一定为空
m_data = new char[strlen(str.m_data) + 1];
strcpy_s(m_data, strlen(str.m_data) + 1, str.m_data);
}
MyString& MyString::operator=(const MyString& str)
{
if (this == &str)
return *this; // 检测自我复制,如果没有这一行会报错
delete[] m_data; // 复制操作先删除原来数据
m_data = new char[strlen(str.m_data) + 1];
strcpy_s(m_data, strlen(str.m_data) + 1, str.m_data);
return *this;
}
std::ostream& operator<<(std::ostream& os, const MyString &str)
{
os << str.get_c_str();
return os;
}
简单测试函数
#include "MyString.h"
#include <iostream>
int main()
{
MyString s1("hello");
MyString s2(s1); // 拷贝构造
MyString s3 = s2; // 这一行与上面等价,都是拷贝构造
MyString s4;
s4 = s3; // 这里是重载赋值运算符
std::cout << s1 << std::endl;
std::cout << s2 << std::endl;
std::cout << s3 << std::endl;
std::cout << s4 << std::endl;
}