zoukankan      html  css  js  c++  java
  • 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

    运行结果:

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

  • 相关阅读:
    ASP.NET 服务器控件属性
    SQL Server CE和.NET Compact Framework概述
    用户控件在父页面上事件处理
    jquery怎么实现点击一个元素更换背景图片,连续点击永远在2张图片之间更换
    javascript函数大全
    在代码运行时或者在禁用“只要一个进程中断,就中断所有进程”选项时,不允许进行更改。
    jquery的html,text,val
    饥饿会让人更聪明
    用jquery解析JSON数据的方法
    AOP与OOP
  • 原文地址:https://www.cnblogs.com/lovemi93/p/7553176.html
Copyright © 2011-2022 走看看