/** 做者: cwl 内容: 带指针类的注意点 c++构造函数,拷贝构造,拷贝赋值 new delete解析 */ #include <bits/stdc++.h> using namespace std; class String { public: String(const char* cstr = 0) { if(cstr) { m_data = new char[strlen(cstr) + 1]; strcpy(m_data, cstr); } else { m_data = new char[1]; *m_data = '\0'; } } ///拷贝构造,接受本身这种东西的引用 String(const String& str) { m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); } ///拷贝赋值,接受本身这种东西的引用 String& operator=(const String &str) { if(this == &str) { return *this; } delete[] m_data; m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); return *this; } ~String() { delete[] m_data; } char* get_c_str() const { return m_data; } private: char* m_data; }; inline ostream& operator << (ostream& os, const String &str) { os << str.get_c_str(); return os; } int main() { /** c++中类四个重要部分 构造函数 析构函数 拷贝构造 拷贝赋值 */ ///[1] 若是你的class若是带着指针,就必须重写拷贝构造和拷贝赋值 /** 构造和析构是带指针的类必备的,而容易被忽略的是下面两个部分。 【1.1】拷贝构造 String(const String& str) { m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); } 可能会有疑问,str中的m_data明明是private为何能直接访问? 答:解释有不少,其中一个是一个类的不一样对象互为友元 【1.2】拷贝赋值 String& operator=(const String &str) { if(this == &str) { return *this; } delete[] m_data; m_data = new char[strlen(str.m_data) + 1]; strcpy(m_data, str.m_data); return *this; } 杀掉原来的,建立一个同大小的空间,返回。 细节是要检测是不是检测自我赋值。 if(this == &str) { return *this; } 多想一步,增强代码稳定性。 下面咱们添加输出 inline ostream& operator << (ostream& os, const String &str) { os << str.get_c_str(); return os; } */ String a = "hello"; cout << a << endl; /** 堆和栈 【1】String a("qqq"); a是栈空间,有操做系统建立在做用域{}结束后释放。 自动,auto,也就是旧的时候的auto语义,c++11前的 【2】String *p = new String("asd"); p在栈空间,执行了new处理的堆空间。须要手动delete 不然会出现[内存泄漏] 【3】static int a; 声明周期扩展被扩张 【4】全局对象 生命在main以前,main结束后才析构 */ ///【new】new 会先申请内存,转形,而后调用构造函数 ///new 的过程 ///注:operator new是一个函数的名字,c++中能查到源代码 /** String *pc; void* mem = operator new(sizeof(String)); 申请空间 pc = static_cast<String*>(mem); 类型转化 pc->String::String("asd"); 调用构造函数,直接调会有问题,这里只是示例 */ ///【delete】delete的过程 /// String::~String(ps) //析构函数 /// operator delete(ps) //释放内存 /** new 和 delete 底层使用malloc和delete得到空间 */ return 0; }