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函数

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

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。