why copy constructor don't need to check 3 things

2024-01-23 05:58

本文主要是介绍why copy constructor don't need to check 3 things,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

拷贝构造函数的相关内容(浅拷贝,深拷贝,赋值运算符)
2008-04-21 14:19

Copy constructor is

  • a constructor function with the same name as the class
  • used to make deep copy of objects.
拷贝构造函数(或者叫复制构造函数)是与构造函数同名的函数,它来实现对象的深拷贝。
什么是深拷贝和浅拷贝?浅拷贝复制的是对象的所有成员的值,对于指针,它只复制指针,而不会复制其指向的动态分配的内存。默认的拷贝构造函数和赋值运算符实现的是浅拷贝。浅拷贝的问题是,如果存在多个指针指向同一处内存,而这段内存在某个时候由于一个对象的结束而被释放,那么其他对象的指针就指向了无效的内存区域!
深拷贝必须通过自己编写拷贝构造函数和重载赋值运算符来实现,它将动态分配的内存也实现拷贝。

There are 3 important places where a copy constructor is called.
  • When an object is created from another object of the same type
  • When an object is passed by value as a parameter to a function
  • When an object is returned from a function
拷贝构造函数主要在下述的三种情况下被调用:
  • 当从另一个同类型的对象中创建对象时

Person q("Mickey"); // constructor is used to build q. no copy constructor
Person r(p); // copy constructor is used to build r.
Person p = q; // copy constructor is used to initialize in declaration.
p = q; // Assignment operator, no constructor or copy constructor
  • 当对象作为一个函数的参数用值传递的方式传递时。

f(p); // copy constructor initializes formal value parameter.

  • 当对象被函数用作返回值返回时。
当对象间赋值的时候,不会调用拷贝构造函数,这时候使用的是赋值运算符,请查看文末的说明。
If a copy constructor is not defined in a class, the compiler itself defines one. This will ensure a shallow copy. If the class does not have pointer variables with dynamically allocated memory, then one need not worry about defining a copy constructor. It can be left to the compiler's discretion.
But if the class has pointer variables and has some dynamic memory allocations, then it is a must to have a copy constructor.
如果不在类中定义拷贝构造函数,编译器会自动定义一个,完成浅拷贝。如果类中没有指针变量指向动态分配的内存, 浅拷贝就OK,那么就没有必要自定义拷贝构造函数
如果有, 必须进行深拷贝的话,则必须定义拷贝构造函数

If you need a copy constructor, you also need a destructor and operator=
如果需要一个拷贝构造函数,那么你同样需要一个析构函数和对赋值运算符=的重载。

例如:
class A //Without copy constructor
{
private:
int x;
public:
A() {x = 10;}
~A() {}
}
class B //With copy constructor
{
private:
char *name;
public:
B()
{
name = new char[20];
}
~B()
{
delete name[];
}
//Copy constructor
//拷贝构造函数的参数必须为const,这样可以防止原来的对象被破坏,同时,它必须是引用,因为如果不是引用而用值传递,那么就需要拷贝,就需要调用拷贝构造函数,就需要拷贝,就需要.....
B(const B &b)
{
name = new char[20];
strcpy(name, b.name);
}
};

Let us Imagine if you don't have a copy constructor for the class B. At the first place, if an object is created from some existing object, we cannot be sure that the memory is allocated. Also, if the memory is deleted in destructor, the delete operator might be called twice for the same memory location.
设想没有为B类定义拷贝构造函数,首先,如果新的对象通过一个已经存在的对象来创建,那么我们不能肯定内存被正确地分配了。并且,内存被析构函数删除,同一处内存可能会被删除两次。
Difference between copy constructor and assignment
拷贝构造函数和赋值的区别
A copy constructor is used to initialize a newly declared variable from an existing variable. This makes a deep copy like assignment, but it is somewhat simpler:
  • There is no need to test to see if it is being initialized from itself.
  • There is no need to clean up (eg, delete) an existing value (there is none).
  • A reference to itself is not returned.
拷贝构造函数从一个已经存在的变量来初始化一个新声明的变量。这使得深拷贝和赋值有些相像。但是更简单:
首先,不需要像赋值运算那样检查是否从自己初始化
其次,不需要清除现有的值(因为是新创建,所以没有现有值)
最后,没有返回值。

赋值运算符的定义如下:
The following steps are a typical for the assignment operator.
  1. No self-assignment. Test to make sure you aren't assigning an object to itself, eg x = x. Of course no one would write that statement, but in can happen when one side of the assignment is not so obviously the same object. Self assignment fails because the memory associated with the current value of the left-hand-side is deallocated before the assignment, which would invalidate using it from the right-hand-side.
  2. Delete the associated memory. Same as copy constructor.
  3. Copy all the members. Same as copy constructor.
  4. Return *this. This is necessary to allow multiple assignment, eg x = y = z;

//--- file Person.h
. . .
class Person {
private:
char* _name;
int _id;
public:
Person& Person::operator=(const Person& p);
. . .
}
//--- file Person.cpp
. . .
//=================================================== operator=
Person& Person::operator=(const Person& p) {
if (this != &p) { // make sure not same object
delete [] _name; // Delete old name's memory.
_name = new char[strlen(p._name)+1]; // Get new space
strcpy(_name, p._name); // Copy new name
_id = p._id; // Copy id
}
return *this; // Return ref for multiple assignment
}//end operator=

如果存在基类,那么在重载赋值运算符时,也必须调用基类的赋值运算符
//--- file Parent.h
class Parent {...}; // declaration of base class
//--- file Child.h
#include "Parent.h"
class Child : public Parent { // declaration of derived class
public:
Child& Child::operator=(const Child& source);
};//end class Child
//--- file Child.cpp
#include "Child.h"
Child& Child::operator=(const Child& source) {
if (this != &source) {
this->Parent::operator=(source);
. . . // copy all our own fields here.
}
return *this;
}//end operator=
其他:
为了防止拷贝和值传递等方式对对象进行错误的赋值,可以将拷贝构造函数定义为私有,并且并不实现她,对赋值运算符也一样。

这篇关于why copy constructor don't need to check 3 things的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/635416

相关文章

SOMEIP_ETS_095: SD_Check_subscribe_eventgroup_ttl_expired

测试目的: 验证DUT(Device Under Test)能够检测到测试器(Tester)的订阅已过期(ttl = 3秒),并且在TTL过期后不响应测试器触发的事件。 描述 本测试用例旨在确保DUT能够识别测试器的订阅已过期,并在订阅过期后不响应测试器通过TriggerEventUint8方法触发的事件。 测试拓扑: 具体步骤: TESTER:发送订阅事件组消息,用于事件组0x0

C函数特性:构造与析构(constructor destructor)

文章目录 0x1 constructor0x2 constructor_priority0x3 destructor0x4 destructor_priority 0x1 constructor attribute((constructor)) 是 GCC 编译器的一个特性,它允许定义一个特殊的函数,这个函数会在 main 函数执行之前,也就是程序开始执行时被调用。 这通常用于执

@vueup/vue-quill使用quill-better-table报moduleClass is not a constructor

quill官方中文文档:https://www.kancloud.cn/liuwave/quill/1434144 扩展表格的使用 注意:想要使用表格 quill的版本要是2.0以后 升级到这个版本后 其他一些插件就注册不了了。 安装: npm install quill@latest   版本需要大于2.0版本 npm install quill-better-table 引入&

Java 入门指南:Java 并发编程 —— Copy-On-Write 写时复制技术

文章目录 Copy-On-Write使用场景特点缺点CopyOnWrite 和 读写锁相同点之处不同之处 CopyOnWriteArrayList适用场景主要特性方法构造方法CopyOnWriteArrayList 使用示例 CopyOnWriteArraySet适用场景主要特性方法构造方法使用注意事项CopyOnWriteArraySet 使用示例 Copy-On-Writ

Unexpected token d in JSON at position 5, check bodyParser config错误解决

错误原因:json格式不对 { desc="设备1", iotProjectId=11 } 解决:通过json在线校验格式校验json格式,找出错误原因,修改 在线JSON校验格式化工具(Be JSON) 修改: {"desc": "设备","iotProjectId": 11}

CtreeCtl check

转载http://www.cnblogs.com/lujin49/p/4573616.html 对进行了修改 void CTestTimerDlg::SetParentCheck(HTREEITEM hTree,BOOL bCheck) {     HTREEITEM hParent = m_TreeCtrl.GetParentItem(hTree);     if (hParent)

移动应用唤起微信无响应,提示 sendReq failed for wechat app signature check failed

问题描述 在接入微信SDK的时候  String appId = Constants.APP_ID; // 填移动应用(App)的 AppId,非小程序的 AppIDIWXAPI api = WXAPIFactory.createWXAPI(context, appId);WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();

2024.9.1 Python,跳跃游戏,贪心算法,回溯算法复原 IP 地址,关于回溯过程中列表的[:]以及copy问题再讨论

先祝各位C友们9月快乐,生活幸福。 1.跳跃游戏,贪心算法 昨天的三个代码我写到最后没时间去盘了,今天来盘一下,昨天我写的第一个代码从逻辑上就有问题,所以不停的报错不停的报错,我在报错的过程中不断地去加可能性,但是加一种可能就只解决一种问题,所以说明问题没有在根本上解决,所以我便在今天去看之前的代码有什么问题,我的代码如下: #错的class Solution:def jump(self,

NumPy(十三):数组的复制【.copy()】

import numpy as np# 数组的复制ar1 = np.arange(10)ar2 = ar1print('ar1 = {0}, ar2 = {1}'.format(ar1, ar2))print('ar2 is ar1: ', ar2 is ar1)# 回忆python的赋值逻辑:指向内存中生成的一个值 → 这里ar1和ar2指向同一个值,所以ar1改变,ar2一起改变ar1

docker实战扩展四( Dockerfile 中,COPY . .详细讲解)

在 Dockerfile 中,COPY . . 是一个常用的指令,它的作用是将构建上下文中的所有文件复制到镜像中的指定目录。为了更好地理解这个指令,我们需要先了解两个概念:构建上下文和容器中的工作目录。 概念解释 构建上下文: 构建上下文是指在执行 docker build 命令时,Docker CLI 将指定目录的内容(包括子目录和文件)发送给 Docker 守护进程。构建上下文的路径通常