我对引用参数有以下问题:当我们有一个带有引用参数的函数时,编译器将自动传递给该函数,即调用它的任何参数的地址。示例(带对象):
class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { if(s) delete [] s; cout << "Freeing s\n"; }
void show() { cout << s << "\n"; }
void set(char *str);
};// Definition will be excluded from here`
我们有一个带有此类实例的引用参数的函数,
喜欢:
void funtionWithRef(sample &kk); // declaration
void funtionWithRef(sample &sam){ // definition
sam.show();
}
和一个返回样本类型对象的函数:
sample functionReturnSample(); //declaration
sample functionReturnSample(){ // definition
sample sam;
sam.set("test sample");
return sam;
}
现在,当我们这样做时:
int main() {
sample temp = functionReturnSample();
funtionWithRef(temp);
return 0;
}
它工作完美。当我们将temp对象作为参数传递给funtionWithRef时,编译器将该对象的地址传递给函数。但是为什么它不起作用,如果我们不首先将functionReturnSample的返回值分配给实例,而是直接将该方法作为参数放入,例如:
funtionWithRef(functionReturnSample());
为什么这会有所不同,当我们做同样的事情时,根据我查阅的一些书籍,应该
编辑
@user657267 这是完整的示例(源书:C++ From Ground Up,第 3 版,第 219-320 页):
class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { cout << "s: " << s <<" ,Freeing s\n"; if(s) delete [] s;}
void show() { cout << s << "\n"; }
void set(char *str);
sample operator=(sample &ob); // overload assignment
};
// Normal constructor.
sample::sample() {
s = new char('\0'); // s points to a null string.
cout << "Normal constructor: s: " << strlen(s) << endl;
}
// Copy constructor.
sample::sample(const sample &ob) {
cout << "Copy constructor: ob.s: "<< ob.s << " ,strlen(ob.s): " << strlen(ob.s) << "\n";
s = new char[strlen(ob.s)+1];
strcpy(s, ob.s);
}
// Load a string.
void sample::set(char *str) {
s = new char[strlen(str)+1];
strcpy(s, str);
}
// Overload assignment operator.
sample sample::operator=(sample &ob) {
/* If the target memory is not large enough
then allocate new memory. */
cout << "operator= strlen(ob.s): " << strlen(ob.s) << " ,strlen(s): " << strlen(s) << endl;
if(strlen(ob.s) > strlen(s)) {
cout << "operator= Larger memory of target object. Deleting current...\n";
delete [] s;
s = new char[strlen(ob.s)+1];
}
strcpy(s, ob.s);
return *this;
}
// Return an object of type sample.
sample input() {
char instr[80];
static sample str;
cout << "Enter a string: ";
cin >> instr;
str.set(instr);
return str;
}
int main() {
sample ob;
// assign returned object to ob
ob=input(); // This is now OK
ob.show();
return 0;
}
这不会编译,并报告错误:
**error: no match for ‘operator=’ (operand types are ‘sample’ and ‘sample’)**
所以它是上述书中代码的副本/过去。你可以检查一下。
但是我弄清楚如果我将重载 = 运算符参数指定为const,例如:
sample operator=(const sample &ob); // overload assignment
然后它确实有效。然而,困扰我的是,现在当我有可运行的代码时,我不明白为什么要调用两次复制构造函数。我知道它在input()函数返回并创建临时对象时被调用,但我不明白为什么第二次,据我所知(但也许我错了)复制构造函数不会被调用用于赋值操作(同一本书,第 291-292 页),但它看起来像,尽管如此,当return *this; 被调用(当重载运算符返回值时),调用复制构造函数?那是怎么回事?谢谢