0

参照パラメーターに関して次の問題があります。参照パラメーターを持つ関数がある場合、コンパイラーはその関数に、呼び出された引数のアドレスを自動的に渡します。例 (オブジェクトあり):

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;のように見えます。が呼び出された場合 (オーバーロードされた演算子が値を返す場合)、コピー コンストラクターが呼び出されますか? それで、それはどうですか?ありがとう

4

0 に答える 0