12

私は Eckel の定数の章を読んでいて、Temporaries が説明されている部分で混乱しました。私が得ることができたのは、関数への参照を渡すと、コンパイラは const オブジェクトである一時オブジェクトを作成するため、参照を次のように渡しても変更できないということでした。

f(int &a){}

ここで、Temporaries の他のリファレンスをオンラインで調べようとしましたが、行き詰まりました

http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage %2Fref%2Fcplr382.htmおよび

C++ ではすべての一時変数は右辺値ですか?

これにより、一時変数は関数内で参照を渡し、そのための const オブジェクトを作成するだけではないことがわかりました。これで、これら 2 つのリンクから何かを得ることができましたが、一時変数としての動作、機能、および使用法を理解しているとは言えませんでした。全体。誰かが一時的な概念を説明できれば、本当に役に立ちます。前もって感謝します。
ブルース・エッケルの元の例は次のとおりです。

// Result cannot be used as an lvalue
class X {
    int i;
    public:
    X(int ii = 0);
    void modify();
};
X::X(int ii) { i = ii; }
void X::modify() { i++; }
X f5() {
    return X();
}
const X f6() {
    return X();
}
void f7(X& x) { // Pass by non-const reference
    x.modify();
}
int main() {
    f5() = X(1); // OK -- non-const return value
    f5().modify(); // OK
    // Causes compile-time errors:
    //! f7(f5());
    //! f6() = X(1);
    //! f6().modify();
    //! f7(f6());
} ///:~
4

4 に答える 4

5

一時オブジェクトは名前のないオブジェクト(一部の式の結果)であり、常に右辺値です。あるいは、右辺値になる式は一時的なものであると言った方がいいかもしれません。

Cでは、右辺値/一時値は実際にはオブジェクトではありませんでした(ある意味で、標準では「オブジェクト」という単語が使用されています。これはメモリ内にあるものです)。したがって、たとえば、それらはcv修飾されておらず(3 + 5has typeintのような式は、ではなくint const、関数の戻り値では無視されます)、それらのアドレスを取得することはできません(メモリ内にないため、彼らは住所を持っていません)。C ++では、問題はクラスタイプによって曇っています。右辺値でメンバー関数を呼び出すことができthis、そのメンバー関数にはポインターがあります。つまり、(クラスタイプの)右辺値でさえメモリ内にアドレスが必要であり、そのcv -修飾には意味があります。戻り型が constの場合、非const関数を呼び出すことができないためです。

結局、右辺値と一時値の概念は非常に密接に関連していますが、C++標準ではわずかに異なる方法で単語を使用しています。式の結果は右辺値または左辺値のいずれかであり(C ++ 11は他の可能性を追加しますが、専門家になるまで無視できます)、この区別はすべての型に関係します。C ++標準が一時的なものについて話すとき、それはオブジェクトである(またはオブジェクトになった)右辺値です。ほとんどの場合、これらにはクラスタイプがあります。テンプレートが関係している場合を除いて、適切に記述されたコードでクラスタイプではない一時的なものが存在する場合はほとんどありません。たとえビルトインであっても、区別は重要です&演算子は右辺値に対して無効です。クラスタイプの右辺値には、定義された「ライフタイム」とメモリアドレスがあります。その寿命は、完全な表現の終わりまでです。したがって、クラスタイプに関しては、一時的な値と名前付きの値の違いは、主に一時的な値に名前がなく、有効期間が異なることです。クラス型の存続期間は、2つの理由で重要です。1つは、デストラクタがいつ呼び出されるかを決定すること、もう1つは、オブジェクトが内部データへのポインタを「リーク」する場合、たとえばstd::string::c_str()、このポインタが有効である期間を決定することです。

最後に、テンプレートについて説明します。これは、非クラス型へのconst参照が存在するのはこのときだけだからです。in引数の通常の規則は、非クラス型の場合は値で渡され、クラス型の場合はconst参照で渡されます。ただし、テンプレートの作成者は、Tクラスタイプになるかどうかを知りません。ほとんどの場合、関数を定義して。を取得しT const&ます。これは、実際には、非クラス型の一時オブジェクトになってしまう唯一の時間です(テンプレートが引数のアドレスを保存している場合は、問題が発生する可能性があります)。

于 2013-02-28T09:18:28.167 に答える