C++入门经典-例7.7-对象与复制,菌类的繁殖

1:当函数以相应的类作为形参列表时,对象可以作为函数的参数传入。在学习函数时,我们曾提过,值传递先复制实参产生副本。那么对象的副本是怎样的呢?

    复制构造函数是指类的对象被复制时所调用的函数。下面两种情况中对象都会调用复制构造函数。

(1)将一个对象赋值给另外一个对象时。例如:

对象1=对象2;

对象1(对象2);

    上面的程序中对象2的复制构造函数会被调用。

(2)作为值传递的实参。例如:

function(对象1);

    在function函数体内,使用的是对象1的副本。所以之前会调用对象1的复制构造函数。

    和构造函数一样,C++在未发现自定义的复制构造函数之前会创建一个默认的构造函数。

    自定义的复制构造函数的声明格式为:

类名(类名& 形参)

    值得注意的是,复制构造函数时引用传递的函数。既然默认复制构造函数已经完成复制工作,那为何需要重新定义它呢?例如,一个类具有指针类型的数据,默认复制构造函数执行之后,原对象和副本的指针成员指向的是同一个内存空间。通过指针改变该内存,就会改变两个对象实际应用的数据(也就是这块内存的内容)。这时可以自定义复制构造函数,将两个指针的内存分离开。

2:代码如下:

(1)germ.h

#include <string>
using std::string;
class germ{
public:
    int m_age;
    string m_name;
    germ(germ& g);//自定义复制构造函数  类名(类名&形参)
    germ(string s);//构造函数
    ~germ();//析构函数,执行收尾工作
    };
View Code

(2)germ.cpp

#include "stdafx.h"
#include "germ.h"
#include <iostream>
using std::cout;
using std::endl;
germ::germ(string s)
{
    m_name = s;
    m_age = 1;
    cout<<"发现了"<<m_name<<endl;
}
germ::germ(germ& g)
{
    g.m_age +=1;
    this->m_age = 1;
    this->m_name =g.m_name + "的复制体"; 
    cout<<"产生了"<<g.m_name<<"的复制体"<<endl;
}
germ::~germ(){
    cout<<this->m_name<<"被消灭了"<<endl;
}
View Code

(3)main.cpp

// 7.7.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "germ.h"
using std::cout;
using std::endl;
germ copyGerm(germ gc)
{
    return gc;
}
int main()
{
    germ g1("有氧菌");//(发现了有氧菌)
    germ g2(g1);//第一个germ的意思是声明一个对象g2,g2(g1)的意思是将g1赋值给g2,此时将会调用复制构造函数(产生了有氧菌的复制体)
    germ g3("无氧菌");//(发现了无氧菌)
    germ g4 = g3;//意思同样是将g3赋值给g4,此时将会调用复制构造函数。(产生了无氧菌的复制体)
    germ g5 = copyGerm(g4);//此时也调用复制构造函数了,只要有副本,就会调用复制构造函数。此处调用了两次,copygerm()一次,等号一次(产生了无氧菌复制体的复制体,产生了无氧菌复制体的复制体的复制体)
    return 0;
}
//注意,调用copygerm后,copygerm会立即被释放,所以会立即放出析构函数,输出(无氧菌的复制体的复制体被消灭了)
//以后依次g5,g4,g3,g2,g1被释放,故依次被输出这些被消灭
View Code

运行结果:

C++入门经典-例7.7-对象与复制,菌类的繁殖

    从程序运行结果来分析代码:首先在主函数中产生了g1对象,由复制构造函数产生了g1的复制体g2——有氧菌复制体。之后定义了g3——无氧菌。通过复制构造函数产生了g3的复制体g4。前四行输出即是上面所述的过程。g5的产生前,g5所在赋值语句等号右边的copyGerm函数被调用,传递的实参为g4——无氧菌的复制体。如同开始提到的,值传递实参对象产生副本,副本就是形参gc——无氧菌复制品的复制品。函数执行完毕后,传递回临时变量,内容是gc。g5的值经过复制语句,所以它是gc(临时变量使用的内存)的复制品。

相关推荐