新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 如何进行拷贝构造函数和运算符重载 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3779 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 如何进行拷贝构造函数和运算符重载 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     葛靖青001 美女呀,离线,快来找我吧!水瓶座1984-2-14
      
      
      等级:大三(研究MFC有点眉目了!)
      文章:168
      积分:595
      门派:XML.ORG.CN
      注册:2010/11/2

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给葛靖青001发送一个短消息 把葛靖青001加入好友 查看葛靖青001的个人资料 搜索葛靖青001在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给葛靖青001 引用回复这个贴子 回复这个贴子 查看葛靖青001的博客楼主
    发贴心情 如何进行拷贝构造函数和运算符重载

    拷贝构造函数应用的场合由以下几个方面:

        1 函数的参数是一个对象,并且是值传递方式

        2 函数的返回值是一个对象,并且是值传递方式

        3 用一个对象初始化另外一个对象

        由此,当函数的参数或者返回值为一个对象时,使用的时候要小心,因为值传递的时候执行的是位拷贝,并不会调用对象的构造函数,也就是说生成的临时对象可能不是正确初始化的,这样就可能会出现一些意向不到的问题。当返回值是个对象和用一个对象初始化另外一个对象时的情况是相同的。

        比如如下代码:

         #include <iostream>

        using namespace std;

        class CTest

        {

        public:

        int i;

        CTest(){cout << "construct" << endl;}

        ~CTest(){cout << "discontruct" << endl;}

        };

        void test(CTest obj)

        {

        }

        int main()

        {

        CTest testObj;

        test(testObj);

        return 0;

        }


        这个程序运行的结果为:

        construct

        discontruct

        discontruct

        调用了一次构造函数,调用了两次析构函数。声明testObj对象时,调用了一次构造函数。当testObj以值传递的方式传入test函数时,此时会生成一个CTest类型的临时变量,但是此时编译器采用的是位拷贝的方式,并不调用CTest类的构造函数。当test函数退出时,生成的临时变量生命周期结束,调用一次析构函数,当main函数退出时,testObj变量生命周期结束,调用一次析构函数。所以出现上面的输出。

        正确的解决方法是定义一个拷贝构造函数。

        拷贝构造函数的类型为:YourClass&(YourClass& object);

        修改后的代码为:

    #include <iostream>

    using namespace std;

    class CTest

    {

    public:

    int i;

    CTest(){cout << "construct" << endl;}

    CTest(CTest& obj){cout << "call copy construct" << endl;} //拷贝构造函数

    ~CTest(){cout << "discontruct" << endl;}

    };

    void test(CTest obj)

    {

    }

    int main()

    {

    CTest testObj;

    test(testObj);

    return 0;

    }


        此时程序的输出为:

        construct

        call copy construct

        discontruct

        discontruct

        当用一个对象初始化另外一个对象时,也对调用拷贝构造函数。

        如

        CTest test1;

        CTest test2 = test1; //调用test1的拷贝构造函数初始化对象test2

        但是对于下面的表达式:

        CTest test1,test2;

        test2 = test1;

        却不会调用CTest的拷贝构造函数,因为test2已经被初始化过了,此时如果想要正确对test2赋值,需要重载运算符=

        运算符重载的方式为 :

    YourClass& operator=(YourClass& obj)

    {

    return *this;

    }


        虽然不编写拷贝构造函数和重载运算符=,在大部分的情况下代码都能正常工作,因为编译器会生成一个默认的拷贝构造函数并且在对象赋值的时候也会作些特殊处理。但是我们不能完全相信系统始终能正常理解你的代码。所以让代码完全在自己的控制之下才是一个好的方法。所以时刻不要忘记编写拷贝构造函数和重载。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    ---人之所以能,是相信能!!

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2010/11/7 11:14:00
     
     GoogleAdSense水瓶座1984-2-14
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 点击这里发送电邮给Google AdSense 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/29 6:58:23

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    62.500ms