C++学习之构造函数、拷贝构造函数

引申问题一:拷贝构造函数中参数是否加const对拷贝构造函数的影响。

网上大多数人对于这个问题的解释只能达到"当你不想对参数进行修改时,就需要加上const关键字"的程度,但是并没有仔细区分这两种情况到底有什么区别。以下面的程序为例:

Dog.h

#ifndef __test_header__Dog__
#define __test_header__Dog__

#include <stdio.h>
class Dog{
public:
    Dog();
    Dog(Dog &dog);
};
#endif

Dog.cpp

#include "Dog.h"
#include <iostream>

using namespace std;

Dog::Dog(){
    cout<<"Dog()"<<endl;
};

Dog::Dog(Dog &dog){
    cout<<"Dog(Dog &dog)"<<endl;
};

Main.cpp

#include <iostream>
#include <string>
#include "Dog.h"
using namespace std;

int main(int argc, const char * argv[]) {
    // insert code here...
    Dog dog1;
    Dog dog2 = dog1;
    return 0;
}

运行后输出结果为:

而如果将Dog dog1修改为const Dog dog1的话,再次编译就会出现错误

提示没有匹配的构造函数,这是因为我们并没有定义一个参数是const Dog &dog的拷贝构造函数。

那么如果我们把程序稍做修改,修改成以下的代码会发生什么情况呢?

Dog.h

#ifndef __test_header__Dog__
#define __test_header__Dog__

#include <stdio.h>
class Dog{
public:
    Dog();
    //Dog(Dog &dog);
    Dog(const Dog &dog);
    //Dog& operator=(Dog &dog);
};
#endif

Dog.cpp

#include "Dog.h"
#include <iostream>

using namespace std;

Dog::Dog(){
    cout<<"Dog()"<<endl;
};

Dog::Dog(const Dog &dog){
    cout<<"Dog(const Dog &dog)"<<endl;
};

Main.cpp

#include <iostream>
#include <string>
#include "Dog.h"
using namespace std;

int main(int argc, const char * argv[]) {
    // insert code here...
    Dog dog1;
    Dog dog2 = dog1;
    return 0;
}

会不会发生因为不存在不带const的拷贝构造函数而发生编译错误呢?答案是不会,因为我们提供了一个带const关键字的拷贝构造函数,所以无论是const Dog dog1还是Dog dog1它们都能够使用带const关键字的拷贝构造函数,因为带const的拷贝构造函数比不带const的拷贝构造函数要求更加严格,所以他可以接受的参数可以是const常量也可以是不带const的变量,这就有点向下兼容的意思。所以在这种情况下如果没有发现不带const的拷贝构造函数时就会调用带const的拷贝构造函数。

到这你可能要问了,如果同时提供了带const和不带const的2种拷贝构造函数情况会如何呢?把Main.cpp修改如下

#include <iostream>
#include <string>
#include "Dog.h"
using namespace std;

int main(int argc, const char * argv[]) {
    // insert code here...
    Dog dog1;
    const Dog dog2;
    Dog dog3 = dog1;
    Dog dog4 = dog2;
    return 0;
}

答案是:

Dog dog1作为等号右边的操作数时会调用不带const的拷贝构造函数。

const Dog dog1作为等号右边的操作数时会调用带const的拷贝构造函数。

下面再来谈谈系统提供的默认拷贝构造函数,系统默认的拷贝构造函数我猜想有两种可能:

第一种:只提供带const的拷贝构造函数,因为它可以兼容不带const的参数

第二种:视情况而定,如果参数带const就构造一个带const的拷贝构造函数,如果参数不带const就构造一个不带const函数

不过纠结于这个没有多大意义。

时间: 2024-12-28 06:41:51

C++学习之构造函数、拷贝构造函数的相关文章

C++ Primer Plus学习笔记之拷贝构造函数

C++ Primer Plus学习笔记之拷贝构造函数 1,什么是拷贝构造函数 拷贝构造函数有两个含义: 首先,它是一个构造函数,当创建一个新对象时,系统自动调用它: 其次,它将一个已经定义过的对象的数据成员逐一对应的复制给新对象: 如果一个类没有显式定义拷贝构造函数,C++编译器可以为该类产生一个缺省的拷贝构造函数.这个缺省的拷贝构造函数采用C的方式,将拷贝对象的内存一个字节一个字节的拷贝到拷贝对象的内存中(内存拷贝): 2,拷贝构造函数的作用 (1)创建一个新对象,并将一个已存在的对象拷贝到这

C++构造函数 &amp; 拷贝构造函数 &amp; 派生类的构造函数 &amp; 虚继承的构造函数

构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载.(摘自百度百科构造函数). 一.最基本的构造函数 1 class Base 2 { 3 public: 4 Base(int var) : m_Var(var) 5 { 6 } 7 private: 8 int m_Var; 9 }; 以上构造函数的执行过程:

学习总结:拷贝构造函数、常量折叠、堆\栈

一.关于拷贝构造函数 1.相同类型的类对象是通过拷贝构造函数来完成整个复制过程的: 2.拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量: 3.三种情况下会调用拷贝构造函数:对象以值传递的方式传入函数参数.对象以值传递的方式从函数返回.对象需要通过另外一个对象进行初始化: 相关博文: http://blog.csdn.net/lwbeyond/article/details/6202256 二.常量折叠 1.编译器进行语法分析的时候,将常量表达

构造函数 、析构函数 、拷贝构造函数 ~~~~~~~~~~拷贝构造函数

拷贝构造函数 1.拷贝构造函数作用: ①:程序中需要新建立一个对象,并用另一个同类的对象对它初始化: ②:当函数的参数为类的对象时,需要建立一个实参的拷贝: ③:函数的返回值是类的对象: 2 格式: 注意:关键字const是为了保护参数值,防止被改变 ///在类外定义,加域符 :: Box::Box(const Box &b) { hei=b.hei; len=b.len; wid=b.wid; } 3. 使用情况即考虑到其作用时 ① 建立一个新的对象 #include<iostream&g

C++的拷贝构造函数

1?  类会提供默认的拷贝构造函数 –默认的拷贝构造函数会完成所有成员的逐个复制 2?  拷贝构造的调用时机: –函数值传递时 –函数返回时 –用同类型的对象初始时 3?  何时需要自定义拷贝构造函数? –类中有指针(或引用 )成员时 –希望自定义对象的拷贝过程时 4?  使用匿名对象简化编程 // // main.cpp // 拷贝构造函数 // // Created by 06 on 15/1/26. // Copyright (c) 2015年 黄永锐. All rights reserv

拷贝构造函数和赋值操作符

假设有一个如下的MyClass类: class MyClass { public: //构造函数 //拷贝构造函数 MyClass(const MyClass& that) : int_data_(that.int_data_), dbl_data_(that.dbl_data_), str_data_(that.str_data_) { } //赋值操作符 MyClass& operator = (const MyClass& that) { if(this != that) {

构造函数、拷贝构造函数和析构函数的的调用时刻及调用顺序

构造函数.拷贝构造函数和析构函数的的调用时刻及调用顺序 对象是由“底层向上”开始构造的,当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止.因为,构造函数一开始构造时,总是要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时,如果无专门说明0,就调用直接基类的默认构造函数.在对象析构时,其顺序正好相反.   下面简单介绍下这三个函数. 构造函数       1.构造函数不能有返回值  

【C/C++学院】(6)构造函数/析构函数/拷贝构造函数/深copy浅copy

1.构造函数 类的初始化即为构造函数.也为:隐式的初始化. 构造函数在对象初始化的时候,自动被调用.隐式的调用. 构造函数分为三种:有参构造函数.无参构造函数.拷贝构造函数. 有参构造函数调用有三种:括号法.等号法.手工法. #include <iostream> using namespace std; class Test { private: int m_a; public: Test()//无参构造函数 { } Test(const Test &obj)//拷贝构造函数 { }

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

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