[转]为什么复制构造函数的参数需要加const和引用

[转]为什么复制构造函数的参数需要加const和引用

一.引言

1.0在解答这个问题之前,我们先跑个小程序,看下调用关系。

#include <iostream>
using namespace std;
class CExample
{
public:
    CExample(int x) :m_nTest(x) //带参数构造函数
    {
        cout<< "constructor with argument."<<endl;
    }
    CExample(const CExample & ex) //拷贝构造函数
    {
        m_nTest = ex.m_nTest;
        cout << "copy constructor."<<endl;
    }
    CExample& operator = (const CExample &ex)//赋值函数(赋值运算符重载)
    {
        cout << "assignment operator." << endl;
        m_nTest = ex.m_nTest;
        return *this;
    }
    void myTestFunc(CExample ex)
    {
    }
private:
       int m_nTest;
};

int main()
{
      CExample aaa(2);
      CExample bbb(3);
      bbb = aaa;
      CExample ccc = aaa;
      bbb.myTestFunc(aaa);
      system("pause");
      return 0;
}

  

1.1【输出结果】

1.2【分析结果】

第一个输出: constructor with argument.     //CExample aaa(2);

这里创建了变量aaa,在创建的同时还带有参数2,那就调用带参数的构造函数

第二个输出:constructor with argument.     //CExample bbb(3);

分析同第一个

第三个输出:assignment operator.                //bbb = aaa;

bbb之前已经创建了,所以这个不会调用构造函数,而只是将aaa赋值给bbb,所以调用赋值函数
第四个输出:copy constructor.                      //CExample ccc = aaa;

这个和上一个的区别就在于:bbb之前已经创建过了,而这里的ccc是在这条语句才创建的,所以这里是在创建ccc的同时将aaa赋值给ccc,所以这句调用的肯定是构造函数,又因为需要将aaa赋值给ccc,所以调用的是拷贝构造函数。

第五个输出:copy constructor.                     //  bbb.myTestFunc(aaa);
这里是调用了一个自己写的myTestFunc函数,其中这个函数中的参数没有采用引用,那就是值传递的方式。就是编译器先创建一个类型为CExample名称为ex的对象,然后将aaa的值传递给ex(值传递方式的特性),将相当于要执行一条CExample ex = aaa的语句。经第四个输出的分析可知,这需要调用拷贝构造函数。所以输出copy constrctor。

二.解答问题

2.1为什么要用引用?

  【错误答案】个人第一反应:为了减少一次内存拷贝。

  【正确答案】由上节的第五个输出分析可知,在执行bbb.myTestFunc(aaa);时,其实会调用拷贝构造函数。如果我们的拷贝构造函数的参数不是引用,那么在bbb.myTestFunc(aaa);时,调用CExample ex = aaa;,又因为ex之前没有被创建,所以又需要调用拷贝构造函数,故而又执行CExample ex = aaa;,就这样永远的递归调用下去了。

  所以, 拷贝构造函数是必须要带引用类型的参数的, 而且这也是编译器强制性要求的。

2.2为什么要用const?

  【正确答案】如果在函数中不会改变引用类型参数的值,加不加const的效果是一样的。而且不加const,编译器也不会报错。但是为了整个程序的安全,还是加上const,防止对引用类型参数值的意外修改。

——如有不对的地方,非常欢迎给予指导!

——【感谢】资料来源于https://www.cnblogs.com/engraver-lxw/p/7580403.html

——【感谢】资料来源于http://blog.csdn.net/tunsanty/article/details/4264738

——【感谢】资料来源于http://blog.csdn.net/sinat_36053757/article/details/70597567

原文地址:https://www.cnblogs.com/ygsworld/p/10347794.html

时间: 2024-08-27 06:35:42

[转]为什么复制构造函数的参数需要加const和引用的相关文章

为什么复制构造函数的参数需要加const和引用

为什么复制构造函数的参数需要加const和引用 一.引言 1.0在解答这个问题之前,我们先跑个小程序,看下调用关系. 1 #include <iostream> 2 using namespace std; 3 class CExample 4 { 5 public: 6 CExample(int x) :m_nTest(x) //带参数构造函数 7 { 8 cout<< "constructor with argument."<<endl; 9 }

关于C++类中的土著民:构造函数,复制构造函数,析构函数

我们初学C++时可能会对类的构造函数,复制构造函数,析构函数有点疑问.整理如下(个人见解,如有错误,还望指正.): 1.构造函数 根据构造函数的定义知它的作用是初始化类的数据成员或内嵌类的对象,所以它的参数表就应该是它要初始化的对象类型.构造函数分三类:默认构造函数.构造函数.委托构造函数. 默认构造函数 默认构造函数没有返回值,没有参数表,没有函数体,如果类内没有显式的定义构造函数,系统会自动生成默认构造函数,如果已经定义了构造函数,但仍需要默认构造函数,可以在默认构造函数参数表后加defau

何时调用C++复制构造函数和拷贝构造函数(转)

1. 何时调用复制构造函数 复制构造函数用于将一个对象复制到新创建的对象中.也就是说,它用于初始化过程中,而不是常规的赋值过程中.类的复制构造函数原型通常如下: class_name(const class_name&); 它接受一个指向类对象的常量引用作为参数.例如,String类的复制构造函数的原型如下: String(const String&); 新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用.这在很多情况下都可能发生,最常见的情况是将新对象显示地初始化为现有的对

复制构造函数和赋值操作符的注意点.

记得在复制构造函数和赋值操作符的参数类型上加上const.正确的复制构造函数应该是X::X(const X&)这种,而不是X::X(X&)这种,这里有两个原因. 第一:绑定一个非const引用到一个临时对象是非法的.使用X::X(X&)作为复制构造函数不会允许复制任何特殊表达式的结果.为什么呢.?因为引用的初始化规则规定了不能将临时变量作为引用的初始化值. 而常量引用除外. 此外:防止修改引用的值(这个大家都知道). 同样的道理: X::operator=(const X&

剑指offer:关于复制构造函数

1:首先参看代码: #include "stdafx.h" #include "iostream" using namespace std; class A { private: int value; public: A(int n) { value=n; } //A(A other)!!这是错误的 // 复制构造函数参数为类对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中 // 若没

[C++参考]拷贝构造函数的参数必须是引用类型

在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值运算符重载)是最基本不过的需要掌握的知识.在effective C++中说过这么一点:拷贝构造函数的参数必须是引用类型的.但是为什么呢? 拷贝构造函数的参数必须是引用类型的 如果拷贝构造函数中的参数不是一个引用,即形如CClass(const CClass c_class),那么就相当于采用了传值的方式(pass-by-value),而传值的方式会调用该类的拷贝构造函数,从而造成无穷递归地调用拷贝构造函数.因此拷贝构造函数的参数必须是

C++中复制构造函数被调用的三种情况

C++中的构造函数 c++中的构造函数分为构造函数,和复制构造函数,相比于构造函数,复制构造函数使用更加方便,快捷.构造函数可以有多个,二复制构造函数只能有一个,因为复制构造函数的参数只能是当前类的一个对象,参数表是固定的,无法重载,若用户没有定义自己的辅助构造函数,系统会自动生成一个复制构造函数,其作用是将参数的之赋予当前的对象.若用户自己定义了复制构造函数,系统则不会生成默认复制构造函数.用户自己定义的复制构造函数功能可以自己构造,不一定执行复制的功能. 复制构造函数同构造函数的功能大体相同

复制构造函数 与 赋值操作函数

1 class Widget{ 2 3 Widget(); //默认构造函数 4 5 Widget(const Widget& rhs); //复制构造函数 6 7 Widget& operator= (const Widget& rhs);//赋值操作函数 8 9 }; 10 Widget w1; //调用默认构造函数 11 Widget w2(w1); //调用复制构造函数 12 w1 = w2 ; //调用赋值操作函数 上面的语句很好理解,但是需要我们注意的是“=”也可以用来

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员)、拷贝构造函数

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员).拷贝构造函数  从概念上将,可以认为构造函数分为两个阶段执行: 1)初始化阶段: 2)普通的计算阶段.计算阶段由构造函数函数体中的所有语句组成. 一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 1.对象成员及其初始化 <span style="font-size:14px;">#include <iostream> using namespace std;