ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

C++-拷贝构造函数

C++-拷贝构造函数

深拷贝与浅拷贝

浅拷贝:类中的缺省拷贝构造函数,对指针形式的成员变量按字节复制,而不会复制指针所指向的内容,这种拷贝方式称为浅拷贝。

#include <iostream>
using namespace std;class Integer{
private:int m_i;public:Integer(int i = 0) {m_i = i;}void printf(void) {cout << m_i << endl;}
};
int main(int argc, const char *argv[])
{Integer a = 100;Integer b = a;//实际是将b的地址指向a的地址b.printf();Integer c(a);//类似与bc.printf();return 0;
}

深拷贝:为了避免浅拷贝遇到的重复重置内存问题,获得完整意义上的对象副本,必须自己定义拷贝构造函数,针对指针的成员变量,实现对指针指向内容的复制。

#include <iostream>
using namespace std;class Integer{
private:int *m_i;public:Integer(int i = 0) {m_i = new int(i);}void printf(void) {cout << *m_i << endl;}~Integer(void) {delete m_i;}Integer(const Integer &that) {m_i = new int(*that.m_i);}
};
int main(int argc, const char *argv[])
{Integer a = 100;Integer b = a;//实际是将b的地址指向a的地址b.printf();Integer c(a);//类似与bc.printf();return 0;
}

拷贝赋值

当两个对象进行赋值操作时,比如“i3 = i2”编译器会讲其处理为“i3.operator = (i2)的成员函数调用形式”,其中“operator=”称为拷贝赋值操作符函数,由该函数完成其赋值运算,其返回结果就是表达式的结果。

如果没有自定义拷贝赋值操作符函数,编译器会为该类提供缺省的拷贝赋值操作符函数,用于完成两个对象的赋值操作。

但是编译器提供的缺省拷贝赋值函数,和缺省拷贝构造函数类似,也是浅拷贝,有“double free”和“内存泄露”的问题,这时需要自定义深拷贝赋值函数。

拷贝赋值符函数格式为:

Integer &operation = (const Integer &that){}/*
Integer:类名称
&operation= :固定写法
that:指针
*/
#include <iostream>
using namespace std;class A{
private:int *m_pi;public:A(int i = 0) {m_pi = new int(i);}void printf(void) {cout << *m_pi << endl;}~A(void) {cout << "~A" <<endl;delete m_pi;}A(const A &that) {m_pi = new int(*that.m_pi);}
};
int main(int argc, const char *argv[])
{A a = 100;a.printf();A b = a;b.printf();b = a;return 0;
}
/*运行结果报错
linux@linux:~/cplusplus$ ./a.out 
100
100
~A
~A
*** Error in `./a.out': double free or corruption (fasttop): 0x09a57008 ***
Aborted (core dumped)
*/

String类的编程实现

实现一个字符串String,为其提供可接受c风格字符串的构造函数、析构函数、拷贝构造函数和拷贝赋值函数。

#include <iostream>
#include <cstring>
using namespace std;class String{
private:char *str;public:String(const char *str) {//类型转换构造函数this->str = new char(strlen(str) +1);strcpy(this->str,str);}String(const String &that) {//拷贝构造函数str = new char[strlen(that.str) +1];strcpy(str, that.str);}String &operator=(const String &that) {//拷贝赋值if (this != &that) {delete []str;//删除原本的地址str = new char[strlen(that.str) +1];//申请新地址strcpy(str, that.str);//拷贝内容到新地址中}return *this;}~String(void) {delete str;}void print(void) {cout << str << endl;}char *c_str(void) {return str;}
};
int main(int argc, const char *argv[])
{String s1 = "hello";//类型转换构造函数s1.print();String s2 = s1;//拷贝构造函数s2.print();String s3 = "world";//类型转换构造函数s2 = s3;//拷贝赋值s2.print();cout << s3.c_str() << endl;return 0;
}

返回列表