参照パラメーターに関して次の問題があります。参照パラメーターを持つ関数がある場合、コンパイラーはその関数に、呼び出された引数のアドレスを自動的に渡します。例 (オブジェクトあり):
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 の戻りオブジェクトを持つ 1 つの関数:
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
その後、それは機能します。しかし、私を悩ませているのは、実行可能なコードを持っているときに、コピー コンストラクターが 2 回呼び出される理由がわからないことです。input()関数が返されたときに呼び出され、一時オブジェクトを作成することは知っていますが、私が知っている限り(しかしおそらく私が間違っている)コピーコンストラクターは代入操作のために呼び出されないため、2回目は理由がわかりません(同じBook 、ページ 291-292) ですが、それにもかかわらず、 return *this;のように見えます。が呼び出された場合 (オーバーロードされた演算子が値を返す場合)、コピー コンストラクターが呼び出されますか? それで、それはどうですか?ありがとう