首页 > 代码库 > 【ThinkingInC++】57、位拷贝和初始化

【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=http://www.mamicode.com/"windows",B.m_data=“linux";

如果未重写赋值函数,将B赋给A;则编译器会默认进行位拷贝,A.m_data=http://www.mamicode.com/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就会产生两个析构函数
}








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