2013-11-22 5 views
7

ポインタとリファレンスについて説明すると、in this question私はこのコードを書いています。コメントの* newは常に間違っています。いつも

MyClass& MyClass::MyInstance() 
{  
    static MyClass & myLocalVariable = * new MyClass(/*parameters*/); 
    return myLocalVariable ; 
} 

1、ユーザーSO本当に印象的な高い評価により、単に述べている: *新は常に間違っています。常に。

私がこれについて語ったのは初めてのことです。それは、すべてが知っておくべき有名なコーディング規格ですか?何の背後にある理由は何ですか?

+7

これは正確にどのように削除されますか? – Nim

+0

origianlの質問では、私はバニラポインタではなく、std :: shared_ptrを使うことについても話しました。 –

+2

'new'の場合は' delete'が必要です。この場合、あなたはできません。 – crashmstr

答えて

9

私は通常は実用的ですが、これは私にとってもあまりにもです!

static MyClass & myLocalVariable = * new MyClass(/*parameters*/); 

真剣に?単純にどうしてですか:

static MyClass myLocalVariable{/*parameters*/}; 
+1

それはポイントです...あなたがシングルトンをやっているなら、この新しいものをする必要はありません。 – Johan

+0

'new'がこの静的オブジェクトに使いたい非常に魅力的なアロケータを使用する場合はどうなりますか? – RedX

+1

@RedX、シングルトンにファンシーアロケータを使用したいのはなぜですか? – Nim

3

もっとも明白な理由は、新しいものが返されたポインタのコピーを保持しないと、その上でdeleteを呼び出すことはないということです。

人間のレベルが上がると、コードを読んでいる人があなたのことを考えなくても、それは決して良いことではありません。

+8

あなたのコードを読んでいる人があなたを殺したいと思うようになります*。 FTFY – Thomas

+0

この場合、オブジェクト参照からポインタを取得できますか? (これは物事について行く良い方法です...) – fjc

+1

@Frank - はい、C++参照はちょうど偽装されたポインタなので、ポインタに簡単に戻ることができます。それはまだひどく見えるものです。 –

0

私は、静的オブジェクトをnewを使用して割り当てることは、メモリがおそらくリークするので危険であると述べました。さらに重要なのは、変数がポインタではなく参照であるため、newによって返されたメモリを決して解放しない可能性はさらに高くなります(参照のアドレスはどれくらいの頻度で削除されますか?)。

0

問題は単なる無駄な割り当て以外にもあります。

誰もそれに対して削除を呼び出さない場合、削除されません。確かに、プログラムが終了してもデストラクタが呼び出されないと、メモリは解放されます。

は、以下のコードでGet()Get2()を使用しての出力を比較します

#include <iostream> 

    struct A 
    { 
     ~A(){std::cout << "Deleted\n";} 
    }; 

    A& Get() 
    { 
     static A & a = *new A; 
     return a; 
    } 

    A& Get2() 
    { 
     static A a; 
     return a; 
    } 

    int main() 
    { 
     //Case 1 
     Get(); 
     //Case 2 
     Get2(); 
    } 

Get2を呼び出すときにGetDeletedを呼び出すときに、このプログラムの出力は何もありません。
つまり、重大でないデストラクタ(例えば、クローズ時のファイルハンドルなど)を持つリソースは、ケース1のプログラム終了時には正しく破棄されませんが、ケース2の場合は破棄されません。

0

生の新所有権を指定していません。私が新しいものを作り、それを返すのであれば、誰がそれを所有していますか?作成する関数/オブジェクトがそれを所有しているのですか?スマートポインタ(std :: shared_ptrとstd :: unique_ptr)を返すと、所有権が指定されます。

所有権を指定しないと、メモリをリークする最も簡単な方法の1つです。私は、プロのプログラマーであっても、人々に所有権を理解させ、それを使用してもらうのが最も難しい時期です。これは、所有権を指定する良い型(スマートポインタ)を使用することによって、ほとんどの場合防止されます。

これらの異なるタイプのポインタは、既存の生ポインタとはちょうど同じ所有権を表します。

newは常に間違っています。それは過大な一般化です。std::shared_ptrは、グローバル関数std::make_sharedを使用して作成されます。 C++ 11では、std::make_uniqueはありませんが、C++ 14で修正されます。 std::unique_ptrを作成する唯一の方法は、新しくを使用することです。std::unique_ptrにポインタを割り当てます。

生ポインタを使用し、手動でnewdeleteを使用する場所もありますが、それらは非常に低いレベルになりがちで、ほとんどのプログラマはほとんど遭遇しません。本当に私はあなたのコードについてたじたじしている何


あなたがnewを使用していることはありませんが、あなたはポインタを逆参照し、参照に代入されます。デストラクタが呼び出されることを保証することはほとんど不可能です。また、メモリがリークする傾向がありますが、静的変数に割り当てる場合、プログラムの終了時に割り当てが解除されるため、メモリリークを実際には見ていません。

私は静的変数を参照よりも値で設定することをお勧めします。これにより、オブジェクトをヒープ上に置くことができなくなります。また、MyClassに応じて、オブジェクトを初期化するためのコードを実行することなく、オブジェクトを実行可能ファイルからメモリにマップすることもできます。

MyClass& MyClass::MyInstance() 
{ 
    static MyClass myLocalVariable(/*parameters*/); 
    return myLocalVariable ; 
} 
関連する問題