【ThinkingInC++】57、位拷贝和初始化

HowMany.cpp

/**
* 书本:【ThinkingInC++】
* 功能:位拷贝和初始化
* 时间:2014年9月21日17:14:30
* 作者:cutter_point
*/

//位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。

#include <fstream>
#include <cstring>

using namespace std;

ofstream out("HowMany.txt");

class HowMany
{
    static int objectCount;
public:
    HowMany() {objectCount++;}
    static void print(const string& msg="") //这里是常数引用
    {
        if(msg.size() != 0)
            out<<msg<<" : ";
        out<<"objectCount="<<objectCount<<endl;
    }
    ~HowMany()
    {
        objectCount--;
        print("~HowMany()");
    }
};

int HowMany::objectCount=0;

HowMany f(HowMany x)    //这里参数也是位拷贝,也就是x和h1指向同一块内存地址的数据,不会调用构造函数
{
    x.print("x argument inside f()");
    return x;   //退出函数,x的作用域出去,x被调用析构函数,析构的其实是h指向的地方
}

int main()
{
    HowMany h;
    HowMany::print("after construct h");
    HowMany h2=f(h);        //这个是按位拷贝过去的,也就是h2和h1在内存中指向的是同一块地方
    HowMany::print("after call to f(h)");

    return 0;   //这里退出函数,调用析构函数,2次,分别是h调用一次和h2调用一次
}

位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。

位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。如果定义两个String对象A和B。A.m_data和B.m_data分别指向一段区域,A.m_data="windows",B.m_data=“linux";

如果未重写赋值函数,将B赋给A;则编译器会默认进行位拷贝,A.m_data=B.m_data

则A.m_data和B.m_data指向同一块区域,

编译器是这样工作的,当是按值传递的方式传递一个对象时,就创立一个新对象。

查IP

如果你要查看计算机网卡的IP地址,Windows的系统在命令提示符下输入“ipconfig”,Linux的系统在命令解释器下输入“ifconfig”

HowMany2.cpp

/**
* 书本:【ThinkingInC++】
* 功能:拷贝构造函数
* 时间:2014年9月21日17:16:15
* 作者:cutter_point
*/

#include <fstream>
#include <string>

using namespace std;

ofstream out("HowMany2.txt");

class HowMany2
{
    string name;    //作为对象的标示
    static int objectCount;
public:
    HowMany2(const string& id="") : name(id)    //构造函数
    {
        ++objectCount;  //构造一个对象就吧数字加1
        print("HowMany2()");
    }

    ~HowMany2() //析构函数,每当类被消除的时候调用
    {
        --objectCount;
        print("~HowMany2()");
    }

    //拷贝构造函数,一个特殊的构造函数,看好了这是一个构造函数,会创建存储空间的
    HowMany2(const HowMany2& h) : name(h.name)  //用引用,值拷贝
    {
        name+=" copy";
        ++objectCount;
        print("HowMany2(const HowMany2&)");
    }

    //static void print(const string& msg="") //这里是常数引用
    void print(const string& msg="") const  //由于print必须访问name元素所以不定义为Static格式了
    {
        if(msg.size() != 0)
            out<<msg<<endl;
        out<<'\t'<<name<<" : "<<"objectCount="<<objectCount<<endl;
    }

};

int HowMany2::objectCount=0;    //静态数据初始化,必须在这里初始化,因为静态没有this指针,不能用构造函数初始化

HowMany2 f(HowMany2 x)  //一个函数参数是一个HowMany2的对象,这里定义类的拷贝,那么所有的拷贝都是复制拷贝,这里也要创建新的空间
{
    x.print("x argument inside f()");
    out<<"Returning from f()"<<endl;
    return x;   //返回值,一个临时量,默认是值传递,为返回的值创建一个新空间,然后析构x
}

int main()
{
    HowMany2 h("h");
    out<<"Entering f()"<<endl;
    HowMany2 h2=f(h);
    h2.print("h2 after call to f()");
    out<<"Call f(), no return value"<<endl;
    f(h);   //这里调用两次析构,第一次析构函数里面的x,第二次析构返回的临时量
    out<<"After call to f()"<<endl;

    return 0;   //这里析构h和h2就会产生两个析构函数
}
时间: 2024-10-25 03:11:47

【ThinkingInC++】57、位拷贝和初始化的相关文章

C语言中的位拷贝与值拷贝浅谈(转载)

注:C语言实现的PHP变量的赋值过程中,就涉及到了 深拷贝和浅拷贝 位拷贝拷贝的是地址(也叫浅拷贝),而值拷贝则拷贝的是内容(深拷贝).深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝. 位拷贝,及"bitwise assignment"是指将一个对象的内存映像按位原封不动的复制给另一个对象,所谓值拷贝就是指,将原对象的值复制一份给新对象. 在用"bitwise assig

PL/SQL跑在Oracle 64位数据库上初始化错误

安装完Oracle(64位).PL/SQL后运行PL/SQL出现如下的错误: 网上查资料说,我的PL/SQL与ORACLE不兼容,即PL/SQL不支持64位的ORACLE,因此得下一个32位的ORCALE客户端并配置相应的参数: 解决步骤小记: 一.下载ORACLE 32位客户端 下载地址:http://www.onlinedown.net/soft/102902.htm(Oracle 10g客户端精简绿色版) 二.解压到ORACLE 安装目录下一个叫product的目录下,并重命名一下(命名不

【转载】C++中的位拷贝和值拷贝

---恢复内容开始--- 原文:C++中的位拷贝和值拷贝 原文:http://blog.csdn.net/liam1122/article/details/1966617 为了便于说明我们以String类为例: 首先定义String类,而并不实现其成员函数. Class String { public: String(const char *ch=NULL);//默认构造函数 String(const String &str);//拷贝构造函数 ~String(void); String &

“位拷贝”和“值拷贝”的区别(c++)

以string类为例: 位拷贝拷贝的是地址,而值拷贝拷贝的是内容. 若定义string类的两个对象为str1,str2.str1._str和str2._str分别指向一块空间. str1._str = "zhang",str2._str = "tian". 若默认拷贝构造函数,即str1(str2).编译器将str2进行一份位拷贝.str1和str2指向同一块空间. 若默认赋值函数,即str1 = str2.编译器将str2的值赋值给str1,进行的也是位拷贝. 无

C语言实现按位拷贝

在程序开发过程中,我们经常会用到按位拷贝一串二进制数,在此提供一个按位拷贝的函数给大家参考,函数源码如下: #define char_t   char   #define uint8_t  unsigned char   #define int8_t   signed char   #define uint16_t unsigned short   #define int16_t  signed short   #define uint32_t unsigned  long int   #def

PL/SQL Developer跑在Oracle 64位数据库上初始化错误

安装完Oracle(64位).PL/SQL Developer后执行PL/SQL出现例如以下的错误: 网上查资料说,我的PL/SQL Developer与ORACLE不兼容,即PL/SQL不支持64位的ORACLE,因此得下一个32位的ORCALEclient并配置对应的參数: 解决步骤小记: 一.下载ORACLE 32位client 下载地址:http://www.onlinedown.net/soft/102902.htm(Oracle 10gclient精简绿色版) 二.解压到ORACLE

centos6.7 64位安装及初始化环境配置

1, 下载centos 64版本http://mirrors.sohu.com/ 2, 最简化安装 3, 有dhcp服务器的使用dhclient 自动获取ip地址 route查看网关和子网掩码 没有dhcp功能的进入网卡配置手动设置静态ip vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth1 HWADDR=00:0C:29:0C:30:A7 TYPE=Ethernet UUID=31aa0c5d-14fb-4346-9d68-fb2c

CentOS 7.3 64位系统硬盘初始化的方法

1. 背景介绍 a. 现在硬盘的容量越来越大,fdisk命令已经无法满足分区要求,因为,fdisk命令只支持2T以下的磁盘分区,大于2T的硬盘需要使用parted命令进行分区操作b. 常用的有msdos和gpt分区表格式,msdos不支持2TB以上容量的磁盘,所以大于2TB的磁盘选gpt分区表格式 2. 操作步骤 2.1 fdisk命令分区及挂载方法 2.1.1 通过fdisk -l查看硬盘信息,以格式化/dev/vdb磁盘为例 2.1.2 输入fdisk /dev/vdb,开始创建分区操作 [

C++ 笔记(待续)

本文摘自:Thinking in C++ Vol.1  (添加部分C++ primer内容.待续...) 目录: 第零章:help and tips 第一章:对象 第二章:c in c++ 第三章:深入理解字符串 第四.五章:实现的隐藏 第六.七章:初始化和清除 第九章:内联函数 第十章:名字控制 第十一章:引用和拷贝构造函数 第十二章:运算符重载 第零章:help and tips [Index] 安装c/c++的帮助文档:yum install man-pages libstdc++-doc