2017-03-28 10 views
1
#include <iostream> 
#include <utility> 
int main() 
{ 
    double* ptr; 
    { 
     double temp = 5.5; 
     ptr = new double(std::move(temp)); 
    } // temp dies here 
    std::cout << *ptr << "\n"; 
    delete ptr; 
} 

私はこれが分かります。しかし、私のポイントは、この "5.5"の値が同じだが動的に割り当てられたアドレスに直接転送されるかどうかである。つまり、tempが現在スコープに入っていなくても、ptrはまだtempを指していますか?変数の有効期間を延長する

短期的な地域の範囲からより長期の記憶域に移行し、その後変数がいつ死ぬかを決定するという巨大な配列だとしましょう。

詳細な説明:

我々はメモリのアドレスAに位置していると仮定します。それはしばらくして死ぬつもりですが、死ぬ前に私たちはクールなトリックを作り、この同じAアドレスをロックして死ぬことにします。だから私たちはそれを生かし続けるために物をコピーする必要はありませんでした。私たちはただそれをロックした。それはC++で可能ですか?

+1

いいえ、アドレスがスタック上にある場合、関数を返すと無効になります。 –

+0

私たちはそれを生かし続けるために何かにコピーする必要はありませんでした._静的なローカル変数やグローバルな静的な静的な変数とよく似ていますか? – txtechhelp

+1

'' std :: move'は '' double'には何もしません。あなたは最後にコピーをします。 – Jarod42

答えて

2

C++では直接サポートされていません。オブジェクトが有効範囲外になると、そのオブジェクトの存続期間は終了し、そのオブジェクトに残っているポインタは無効です(つまり、参照解除すると、未定義の動作が呼び出されます)。

しかし、これはコード内で何が起こっ本当にではありません。ここでstd::move

double* ptr; 
{ 
    double temp = 5.5; 
    ptr = new double(std::move(temp)); 
} // temp dies here 

はノーオペレーション(何もしない)で、コードがより簡単バリアント

double* ptr; 
{ 
    double temp = 5.5; 
    ptr = new double(temp); 
} // temp dies here 
に相当します

doubleオブジェクトは動的に割り当てられ、5.5で初期化されます。ここで特別なものはありません。

しかし、1つのdoubleオブジェクトの代わりに巨大な配列を持っている場合はどうなりますか?次に、おそらくstd::vectorまたはstd:valarrayを使用していて、そのデータ要素は常に動的に割り当てられます。その後、それは例のようにstd::moveを使用することは理にかなって、それはちょうど右の振る舞いがあります。

また
std::vector<double> values; 
{ 
    std::vector<double> temp; 
    // fill the temp array 
    if (... want to extend life time of temp ...) 
    { 
     values = std::move(temp); 
    } 
} // temp dies here 
// now 'values' is either empty or holds the temp values 

、あなたがstd::arrayまたは組み込み配列型を使用している場合、あなたは(できない自分の価値観をコピーする必要があります移動)。

0

C++ reference - std::moveからのstd ::移動は、オブジェクトTが別のオブジェクトに対するTからリソースの効率的な転送を可能にする、すなわち、「から移動」することができることを示すために使用されます。

特に、std :: moveは引数tを識別するxvalue式を生成します。 rvalue参照型へのstatic_castとまったく同じです。

xvalue、rvalue ...とは何ですか?すべてのCPL式は「右手モード」で評価することができますが、表現の唯一の特定の種類は、左「の意味を持ちます:

プログラミング言語CPLは、式の値カテゴリを導入した最初

C++ reference - value_categoryから - ハンドモード "。右手モードで評価されるとき、式は値(右辺値または右辺値)の計算のルールとみなされます。左手モードで評価すると、式は事実上アドレス(左辺値、左辺値)を与えます。ここでの「左」と「右」は「割り当ての左」と「割り当ての権利」を表していた。

C++ C++ 11に移動セマンティクスの導入により

11は、値の種類は、式の二つの独立した性質を特徴づけるために再定義された[5]:

が同一を有します。その表現が、(直接的または間接的に取得された)オブジェクトのアドレスまたはそれらが識別する関数を比較することによって、表現が別の表現と同じエンティティを参照するかどうかを判断することが可能である。

から移動できます。移動コンストラクタ、移動代入演算子、または移動セマンティクスを実装する別の関数オーバーロードは、式にバインドできます。 C++ 11では

、表現:

  • はアイデンティティを持っていると左辺値の式と呼ばれているから移動することはできません。
  • はアイデンティティを持ち、そこから移動できるものはxvalue式と呼ばれます。
  • は、同一性を持たず、移動可能であり、prvalue( "純粋な値")表現と呼ばれます。
  • アイデンティティがなく、移動できないものは使用されていません[6]。

IDを持つ式は「glvalue式」と呼ばれます(glvalueは「一般化された左辺値」を表します)。左辺値と右辺値は両方ともglvalue式です。

移動可能な式は「rvalue式」と呼ばれます。 prvaluesとxvaluesは両方ともrvalue式です。

  • temp(double)は "identity"を持っています。だから値が使用されます
  • TEMP(ダブル)「から移動すること」ができない

  • 欠けているので、「コンストラクタを移動し、代入演算子、または意味を動かす実装し、別の関数のオーバーロードを移動すると、」

新しい変数を構築する。

関連する問題