一个以引用作为参数的函数无法接收一个常量作为实参

亚信的面试题如下:

#include "iostream"
#include "string"
using namespace std;
class Class1{
public:
 Class1(char *){};
};
void f(Class1 &){};
void main()
{
 f("string");
}

请指出上述代码的错误,并改正之。

直接编译上述代码,得到的结果是:

  “cannot convert parameter 1 from 'const char [7]' to 'Class1 &'”,意思就是无法将一个常字符数组转换为一个Class1的引用。

我们已经有Class1的构造函数,f是f能够将常字符数组隐式地转换为一个Class1的。那么问题肯定就出现在“引用”上了。

让我们来看一下f在接收到“string”这个常字符串的时候后做了哪些工作,首先是调用class1的构造函数,在临时变量区生成一个class1的临时变量(下文用A来称呼它),并用“string”初始化之。

         重点是,这个临时变量的是一个常量,而f函数的形参是一个class1的引用,一个变量的引用就是变量的别名。实质上,变量名和引用名都指向同一段内存单元。如果形参为变量的引用名,实参为变量名,则在调用函数进行虚实结合时,并不是为形参另外开辟一个存储空间(常称为建立实参的一个拷贝),而是把实参变量的地址传给形参(引用名),这样引用名也指向实参变量。如果我们允许将A作为class1的引用传递给f,那么f就能够在它的函数体里面去修改A的值了,这个与A是常量的这个属性相矛盾。

        所以要改正这段代码有两条途径,第一,把f的形参变为class1 而不是class1 &, 即“void f(Class1 ){}”这时,系统在传递参数给f的时候,就会另外开辟一个空间保存A的一个副本,在f中对形参的修改都是对这个副本的修改,而A则不会有任何改变,也就不会与A是常量这个属性相矛盾了。第二,就是把f的形参写成const Class1 &,即"void f(const Class1 &){}"这是系统在传递参数给f的时候,没有另外开辟一个空间,而是让形参指向实参A的内存区域,但是由于形参也是const的,所以在f函数体内,系统不允许对A的任何修改,这样也不会与A是常量这个属性相矛盾了。

 

 

 

 

 

 

你可能感兴趣的:(工作,String,面试,存储,Class)