简介

对象的创建中,常常有这样的需求,就是把对象复制一份。

而复制有三种方法:

1.通过初始化来复制

例如:Object o1(10); Object o2=o1;

2.通过赋值来复制

例如:Object o1(10); Object o2; o2=o1;

3.通过默认拷贝函数来复制

例如:Object o1(10); Object o2(o1);

实际上,第一种方法内部原理是执行了第三种的拷贝函数,默认的拷贝函数是浅拷贝,也就是说只能对基本类型数值进行拷贝

Object类如下:

class Object
{
private:
int _num;
public:
Object(int num)
{
_num=num;
} };

分析

第一种复制对象方法原理(初始化复制)

1.首先 Object o2=o1 这句是先执行了o1的默认拷贝函数

此处o1的默认拷贝函数申明为: Object(const Object& obj),该实现体为编译器默认的浅复制方法实现,因此对于含有复杂变量的类,需要重写该函数

2.然后执行o1的拷贝函数后返回一个匿名对象

3.最后将该匿名对象命名为o2

第二种复制方法原理(赋值复制)

*该原理较为简单,就是直接将简单基本变量值拷贝一份赋值给拷贝对象

第三种复制方法原理(拷贝函数复制)

*第一种原理已解释


实例

代码

Object.h

class Object
{
private:
int _num;
public:
Object(int num)
{
_num=num;
} int getNum()
{
return _num;
} };

main.cpp

#include <iostream>
#include "Object.h"
using namespace std; int main(int argc, char** argv) { Object o1(10);
Object o2=o1;
cout<<o2.getNum()<<endl; Object oo1(20);
Object oo2(10);
oo2=oo1;
cout<<oo2.getNum()<<endl; Object ooo1(30);
Object ooo2(ooo1);
cout<<ooo2.getNum()<<endl; return 0;
}

运行结果


提升

代码

Object.h

#ifndef OBJECT_H
#define OBJECT_H #include <stdlib.h>
#include <string.h> class Object
{
private:
char *_name;
public:
Object(char *name)
{
_name=(char*)malloc(sizeof(char)*(strlen(name)+1));
strcpy(_name,name);
} }; #endif

main.cpp

#include <iostream>
#include "Object.h"
using namespace std; void Test()
{
Object o1("test");
Object o2(o1);
} int main(int argc, char** argv) { Test();
return 0;
}

*这段代码在较为严格的编译器中会报错,这是因为默认拷贝函数是浅拷贝,对基本的值进行拷贝

*然而o2拷贝o1的值时,拷贝的是_name的值,在栈中也就是字符串的地址值,因此拷贝后的o2的_name只是引用了o1的_name指向的字符串

*因此在Test函数结束时,首先o2被析构,其_name指向的字符串被回收。然后o1被析构,其_name指向的字符已在o2析构时被回收,因此o1的_name是野指针,因此产生错误。

改进代码

Object.h

#ifndef OBJECT_H
#define OBJECT_H #include <stdlib.h>
#include <string.h> class Object
{
private:
char *_name;
int _num;
public:
Object(int num,char *name)
{
_num=num;
_name=(char*)malloc(sizeof(char)*(strlen(name)+1));
strcpy(_name,name);
} Object(const Object& obj)
{
_name=(char*)malloc((sizeof(char)*strlen(obj._name)+1));
strcpy(_name,obj._name);
} }; #endif

C++拷贝对象的更多相关文章

  1. Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)

    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 一个很好的例子: # -*-coding:utf-8 -*- ...

  2. 夺命雷公狗—angularjs—23—copy拷贝对象

    copy这在angularjs中是一个拷贝对象的方法: <!DOCTYPE html> <html lang="en" ng-app="myapp&qu ...

  3. 使用copy来拷贝对象

    拷贝对象 您通过将 copy 消息发送给对象,以制作对象的副本. NSArray *myArray = [yourArray copy]; 要拷贝,接收对象的类必须遵守 NSCopying 协议.如果 ...

  4. Java 使用反射拷贝对象一般字段值

    在<Java解惑>上面看到第八十三例--诵读困难者,要求使用非反射实现单例对象的拷贝.查阅了部分资料,先实现通过反射拷贝对象. 1. 编写需要被拷贝的对象Person package co ...

  5. 读书笔记 effective c++ Item 12 拷贝对象的所有部分

    1.默认构造函数介绍 在设计良好的面向对象系统中,会将对象的内部进行封装,只有两个函数可以拷贝对象:这两个函数分别叫做拷贝构造函数和拷贝赋值运算符.我们把这两个函数统一叫做拷贝函数.从Item5中,我 ...

  6. python中拷贝对象的区别

    一.赋值.引用 在python中赋值语句总是建立对象的引用值,而不是复制对象.因此,python变量更像是指针,而不是数据存储区域 这点和大多数语音类似吧,比如C++.Java等 1.先看个例子: v ...

  7. c# 表达式目录树拷贝对象(根据对象类型动态生成表达式目录树)

    表达式目录树,在C#中用Expression标识,这里就不介绍表达式目录树是什么了,有兴趣可以自行百度搜索,网上资料还是很多的. 这里主要分享的是如何动态构建表达式目录树. 构建表达式目录树的代码挺简 ...

  8. 为什么阿里Java手册推荐慎用 Object 的 clone 方法来拷贝对象

    图片若无法显示,可至掘金查看https://juejin.im/post/5d425230f265da039519d248 前言 在阿里Java开发手册中,有这么一条建议:慎用 Object 的 cl ...

  9. C#实现拷贝对象

    大家都知道,在C#中变量的存储分为值类型和引用类型两种,而值类型和引用类型在数值变化是产生的后果是不一样的,值类型我们可以轻松实现数值的拷贝,那么引用类型呢,在对象拷贝上存在着一定的难度.     下 ...

随机推荐

  1. Bootstrap学习笔记(三) 网格系统

    4-1实现原理 网格系统的实现原理非常简单,仅仅是通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统.Boo ...

  2. zabbix短信网关调用问题总结

    在写调用短信网关的shell脚本的时候,发现了一个百思不得其解的问题,用浏览器访问短信接口地址是可以成功接收到短信的.但在shell 里面调用就报错了!!!在反复测试当中发现,在shell 中对特殊字 ...

  3. L004-oldboy-mysql-dba-lesson04

        L004-oldboy-mysql-dba-lesson04 [root@web01 mysql]# mysql -uroot -ptestpassword -S /tmp/mysql.soc ...

  4. JQuery 预热

    这是第一次在博客园写随笔,之所以有这样的冲动是因为每次看到很多园友不断的发表文章,记录下自己的点点滴滴,内心就在不断的忏悔,我很敬佩这种人,不管他们表达的东西是初级还是精辟,我认为只要去坚持写了就是一 ...

  5. 利用cglib生成动态java bean

    cglib详细学习 http://blog.csdn.net/u010150082/article/details/10901641 cglib-nodep jar报下载 http://grepcod ...

  6. [DevExpress]ChartControl之创建X,Y轴Title示例

    关键代码: /// <summary> /// 设置X轴Title /// </summary> /// <param name="chart"> ...

  7. DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾

    #### DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾 #### <style type="text/css"> .test_box { width ...

  8. javascript学习笔记(5

    1.string Array Date Math 内置对象的属性和方法? 答案: ①String 字符串 属性 :length  获取字符串长度 方法: indexOf()  从左到右检索子字符串在原 ...

  9. 使用WebGL实现一个Viewer来显示STL文件

    关键字:WebGL,STL,ThreeJS,Chrome,Viewer,Python3.4, HTML5,Canvas. OS:Windows 10. 本文介绍如何使用ThreeJS来实现一个WebG ...

  10. 不得不知道的Python字符串编码相关的知识

    开发经常会遇到各种字符串编码的问题,例如报错SyntaxError: Non-ASCII character 'ascii' codec can't encode characters in posi ...