C++对象的拷贝与赋值操作
我发现一些同事在编写一个类时,知道什么时候需要实现拷贝构造函数和赋值操作,但不知道什么时候拷贝构造函数被调用,什么时候赋值操作被调用,甚至把二者混为一谈。
要弄明白这个问题,最简单的做法莫过于写个测试程序试一下。不过那样做也未必是好办法,实验的结果往往导致以偏概全的结论。不如好好想一下,弄清楚其中的原理,再去写程序去验证也不迟。
拷贝构造函数,顾名思义,等于拷贝 + 构造。它肩负着创建新对象的任务,同时还要负责把另外一个对象拷贝过来。比如下面的情况就调用拷贝构造函数:
CString str = strOther;
赋值操作则只含有拷贝的意思,也就是说对象必须已经存在。比如下面的情况会调用赋值操作。
str = strOther;
不过有的对象是隐式的,由编译器产生的代码创建,比如函数以传值的方式传递一个对象时。由于看不见相关代码,所以不太容易明白。不过我们稍微思考一下,就会想到,既然是根据一个存在的对象拷贝生成新的对象,自然是调用拷贝构造函数了。
两者实现时有什么差别呢?我想有人会说,没有差别。呵,如果没有差别,那么只要实现其中一个就行了,何必要两者都实现呢?不绕圈子了,它们的差别是:
拷贝构造函数对同一个对象来说只会调用一次,而且是在对象构造时调用。此时对象本身还没有构造,无需要去释放自己的一些资源。而赋值操作可能会调用多次,你在拷贝之前要释放自己的一些资源,否则会造成资源泄露。
明白了这些道理之后,我们不防写个测试程序来验证一下我们的想法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class CString
{
public:
CString();
CString(const char* pszBuffer);
~CString();
CString(const CString& other);
const CString& operator=(const CString& other);
private:
char* m_pszBuffer;;
};
CString::CString()
{
printf("CString::CString/n");
m_pszBuffer = NULL;
return;
}
CString::CString(const char* pszBuffer)
{
printf("CString::CString(const char* pszBuffer)/n");
m_pszBuffer = pszBuffer != NULL ? strdup(pszBuffer) : NULL;
return;
}
CString::~CString()
{
printf("%s/n", __func__);
if(m_pszBuffer != NULL)
{
free(m_pszBuffer);
m_pszBuffer = NULL;
}
return;
}
CString::CString(const CString& other)
{
if(this == &other)
{
return;
}
printf("CString::CString(const CString& other)/n");
m_pszBuffer = other.m_pszBuffer != NULL ? strdup(other.m_pszBuffer) : NULL;
}
const CString& CString::operator=(const CString& other)
{
printf("const CString& CString::operator=(const CString& other)/n");
if(this == &other)
{
return *this;
}
if(m_pszBuffer != NULL)
{
free(m_pszBuffer);
m_pszBuffer = NULL;
}
m_pszBuffer = other.m_pszBuffer != NULL ? strdup(other.m_pszBuffer) : NULL;
return *this;
}
void test(CString str)
{
CString str1 = str;
return;
}
int main(int argc, char* argv[])
{
CString str;
CString str1 = "test";
CString str2 = str1;
str1 = str;
CString str3 = str3;
test(str);
return 0;
}
分享到:
相关推荐
C++ 拷贝构造函数 赋值构造函数 解释
C++拷贝构造函数和赋值操作 拷贝构造函数对同一个对象来说只会调用一次,而且是在对象构造时调用。此时对象本身还没有构造,无需要去释放自己的一些资源。而赋值操作可能会调用多次,你在拷贝之前要释放自己的一些...
深浅拷贝 类的定义 C++ 源代码
本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数、什么情况下调用赋值运算符。最后,简单的分析了下深拷贝和浅拷贝的问题。有需要的朋友可以看下
C++智能指针实现(包含拷贝构造,赋值函数,引用解引用重载) 帮助初学者掌握智能指针的实现原理,采用引用计数方式实现
C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象时,它...
(2) 使用对象指针实参仅将对象的地址值传给形参,而不进行副本的拷贝,这样可以提高运行效率,减少时空开销。 当形参是指向对象指针时,调用函数的对应实参应该是某个对象的地址值,一般使用&后加对象名。下面举...
类的拷贝赋值运算符。 类的析构。 好了one by one 如果我们没有定义类的拷贝构造函数的话,那么编译器会为我们合成默认拷贝构造函数—-合成拷贝构造函数。 和成拷贝构造函数的操作是将其参数的各个成员拷贝到正在...
(5)定义拷贝构造函数并调用。 2.创建一个对象数组,数组的元素是学生对象,学生的信息包括学号、姓名和成绩,在main函数中将数组元素按学生成绩从小到大的顺序进行排序并显示。 三、程序代码
您可能感兴趣的文章:浅谈c++构造函数问题,初始化和赋值问题详解C++ 拷贝构造函数和赋值运算符详解C++中对构造函数和赋值运算符的复制和移动操作C++中复制构造函数和重载赋值操作符总结深入C++中构造函数、拷贝构造...
1.赋值操作符重载的原因 赋值操作符是一个使用频率最高的操作之一,通常情况下它的意义十分明确,就是将两个同类型的变量的值从一端(右端)传到另一端(左端)。但在以下两种情况下,需要对赋值操作符进行重载。 一...
默认的(=)赋值操作符仅完成浅拷贝 默认的赋值操作符和默认的拷贝构造函数有相同的存在意义 (=)赋值操作符注意事项 首先要判断两个操作数是否相等 返回值一定是 return *this; 返回类型是Type&型,避免连续使用=后,...
C++对象的复制 有时需要用到多个完全相同的对象,例如,同一型号的每一个产品从外表到内部属性都是一样的,如果要对每一个产品分别进行处理,就需要建立多个同样的对象,并要进行相同的...可以看到,它与定义对象的方式
这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义; 2.复制构造函数和重载赋值操作符的调用时机; 3.复制构造函数和重载赋值操作符的实现要点; 4....
今天突然被搞蒙,重新复习了一下 多说无益,直接上代码 #include #include using namespace std; class A { public: char * x; int y; A() { cout<<无参构造<x>y=0; } A(int n) ...拷贝构造<x>x,a.x
拷构造与拷赋值浅拷与深拷提到拷控制,就不得不提到浅拷和深拷这个常重要的概念我们根指针做个常简单的释义浅拷拷指针的地址,也就是拷之后结果是两根指针指向同块内存区域
主要介绍了详解C++ 编写String 的构造函数、拷贝构造函数、析构函数和赋值函数的相关资料,这里提供实例帮助大家理解掌握这部分内容,需要的朋友可以参考下
C++实现 类string的 普通构造函数, 拷贝构造函数 析构函数 和赋值函数
用同一个类的源对象构造一个目标对象时,会调用拷贝构造函数来构造目标对象,如果没有定义拷贝构造函数,将调用类的默认拷贝函数来构造目标对象。2 . 当一个函数的返回值为一个类的对象时,如果在调用函数中,没有...