首页 > 代码库 > C++类的拷贝构造(Copy constructor)函数隐藏陷阱
C++类的拷贝构造(Copy constructor)函数隐藏陷阱
好长时间没写C++了,今天写了个很简单的String类,竟然调试了半天,最终发现了一个十分隐蔽的陷阱,写出来供大家分享。
C++中类的拷贝构造函数的作用就是通过类的一个对象来实例化另一个对象。下面是我写的一个MyString类,头文件MyString.h:
#include <iostream> using namespace std; class MyString { public: MyString(); MyString(const MyString& str);//这里就是我们研究的地方 MyString(char *p); ~MyString(); friend ostream& operator<<(ostream& out,MyString& ms) { return out<<"m_Data=http://www.mamicode.com/"<再看看第一个类的实现版本: #include <cstring> #include "MyString.h" using namespace std; MyString::MyString():m_Length(1),m_Data(new char[m_Length]) { memcpy(m_Data,"",m_Length); } MyString::MyString(const MyString& str) :m_Length(str.m_Length),m_Data(new char [m_Length])//这里使用的是new char[],另外说一声,这里的m_Length和m_Data的初始化顺序不能改变,原因自己想就知道了 { memcpy(m_Data,str.m_Data,m_Length); } MyString::MyString(char *p):m_Length(strlen(p)+1),m_Data(new char[m_Length]) { memcpy(m_Data,p,m_Length); } MyString::~MyString() { //注意此处; delete [] m_Data; }使用一个简单的例子来测试(test.cpp):#include "MyString.h" #include <iostream> using namespace std; int main() { MyString b("backup"); MyString a(b); cout<<a<<endl; }结果就是大家熟悉的
再看一下MyString类的第二个实现版本(MyString.cpp)#include <cstring> #include "MyString.h" using namespace std; MyString::MyString():m_Length(1),m_Data(new char[m_Length]) { memcpy(m_Data,"",m_Length); } MyString::MyString(const MyString& str) :m_Length(str.m_Length),m_Data(str.m_Data)//这里直接复制指针; { //memcpy(m_Data,str.m_Data,m_Length); } MyString::MyString(char *p):m_Length(strlen(p)+1),m_Data(new char[m_Length]) { memcpy(m_Data,p,m_Length); } MyString::~MyString() { //注意此处; delete [] m_Data; }运行结果就是:
原因其实很简单,设置断点调试一下就知道了。
在第二个版本中,我们直接复制指针,之后的输出没有问题("m_Data=http://www.mamicode.com/backup"),而根据拷贝构造函数,对象a和b都指向同一个字符数组,执行b的析构函数之后该字符数组的内存空间就没有了,再执行a的析构函数,delete不存在的内存空间就会出现错误了啦。
总结一句:C++还真不愧数一数二难的编程语言,错误都较难发现而且一般都想不到。
C++类的拷贝构造(Copy constructor)函数隐藏陷阱
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。