zoukankan      html  css  js  c++  java
  • 为什么拷贝构造函数的参数必须是引用?

    为什么拷贝构造函数参数必须是引用

    (2011-10-12 17:31:21)

     

    例子:inline Account::
    Account( const Accout &rhs )
    : _balance( rhs._balance )
    {
       _name = new char[ strlen(rhs._name)+1 ];
        strcpy( _name, rhs._name );
       // 不能拷贝 rhs._acct_nmbr
      _acct_nmbr = get_unique_acct_nmbr();

    }

    int main()

    {

    Account acct2( acct1 );

    }

    问题:为什么拷贝构造函数Account( const Accout &rhs )不能写成Account( const Accout rhs )?

    解答:首先你要明白普通的函数,像这样的Account acct2( acct1 );如果参数是引用,是会默认调用一次拷贝构造函数的。

    所以如果有一个函数Account( const Accout rhs ),在参数传递的时候要调用拷贝构造函数也就是自己,调用自己的时候又是一次参数传递,所以又要调用一次自己,调用自己的时候又是一次参数传递,所以又要调用一次自己,……以下省略无限多字。

    注:在c++primer第三版中有解释。
    =============================================================

    今天又想到了这个问题。其实当初我写这篇blog的时候应该不是很明白的。
    (1)拷贝构造函数参数为什么不能是值?用反证法说明。

    Account account2(Account  account1);
    不是要调用拷贝构造函数Account(Account account)吗?这个不就是自己吗?
    所以是自己调用自己。死循环了。

    (2)拷贝构造函数参数为什么不能是指针?
    关于这个问题我是想了很久的,到现在还没有确定原因对不对,因为我没有在一本教科书上看到过答案(thinking in c++里只是简单的带了一下过:But that object can’t be passed into the constructor by value because you’re trying to define the function that handles passing by value, and syntactically it doesn’t make sense to pass a pointer because, after all, you’re creating the new object from an existing object
    我们知道拷贝构造函数在三个地方会用到:分别是,
    a.将一个对象构造为另一个对象的完全副本。(显式)classa_1=class_2;
    b.函数的形参有用到类对象却没有用引用或传址技术时(隐式)
    c.函数的返回值是一个对象却没有用引用或传址技术时(隐式)。
    我觉得b和c两种情况是无所谓的。只是a那种情况,你需要写成T t2(&t1)或者
    T t2=&t1,这样的形式别扭吗?很别扭把。所以用指针也不太合适。
    所以 不用指针是出于美感上的考虑,如果死认指针又有何不可呢?
    另外在more effective c++ item25中讲到了虚拷贝构造函数的东东。

    还有一种特殊种类的虚拟构造函数――虚拟拷贝构造函数――也有着广泛的用途。虚拟拷贝构造函数能返回一个指针,指向调用该函数的对象的新拷贝。因为这种行为特性,虚拟拷贝构造函数的名字一般都是copySelf,cloneSelf或者是象下面这样就叫做clone。很少会有函数能以这么直接的方式实现它。
    
    class NLComponent {
    
    public:
    
      // declaration of virtual copy constructor
    
      virtual NLComponent * clone() const = 0;
    
      ...
    
    };
    
    class TextBlock: public NLComponent {
    
    public:
    
      virtual TextBlock * clone() const         // virtual copy
    
      { return new TextBlock(*this); }          // constructor
    
      ...
    
    };
    
    class Graphic: public NLComponent {
    
    public:
    
      virtual Graphic * clone() const            // virtual copy
    
      { return new Graphic(*this); }             // constructor
    
      ...
    }
    
    

     作者所谓的virtual Graphic * clone() const 就是虚拟拷贝构造函数,厉害吧。其实这个是广义上的虚拟拷贝构造函数,他符合(1)虚拟,只向谁就是谁。(2)拷贝构造函数,在 clone() 成员函数中,代码 new TextBlock(*this); 调用 TextBlock的拷贝构造函数来复制this的状态到新创建的TextBlock对象。

     
  • 相关阅读:
    搭建一个简单的springMVC框架
    java枚举使用
    java中枚举类型的使用
    java递归算法
    JAVA递归算法及经典递归例子 对于这个汉诺塔问题
    java斐波纳契数列
    要求给一个数值,计算它的阶乘
    AcWing2193 分配问题(二分图最优匹配)
    2020上海大学校赛L 动物森友会(网络流+二分)
    BZOJ2654 tree(wqs二分)
  • 原文地址:https://www.cnblogs.com/jeanschen/p/3225597.html
Copyright © 2011-2022 走看看