web-dev-qa-db-ja.com

new演算子を使用して、または使用せずにオブジェクトを初期化する

クラスRectangleがある場合

class Rectangle{

private:
    double width;
    double height;


public:
void    Set(double w , double l){
    width   = w;
    height  = l;
}
};

そして、私はそのようなオブジェクトを明確にします:

Rectangle *Obj;

そして、そのプロパティを初期化してみてください:

Obj->Set(3,5);

コンパイラーは実行時に表示します:The variable 'Obj' is being used without being initialized.

問題は次の方法で解決できます。

Rectangle *Obj=new Rectangle;

その理由について尋ねます!また、コンパイル時にコンパイラがエラーを表示しないのはなぜですか?

22
Aan
Rectangle *Obj;

クラスRectangleのオブジェクトにpointerを定義するだけです。ポインターを定義しても、オブジェクト自体用のメモリーは予約されず、ポインター専用になります。したがって、ポインタにアクセスすると、プロセスに属さないメモリ内のアドレスに到達する可能性が高くなります。ただし、コンパイラは、ユーザーがポインターを初期化していないことを認識できないため(ここでのキーワードはエイリアスです)、エラーメッセージを出力できません。

解決策は、提案したようにnewを使用するか、Rectangleのインスタンスを次のように宣言することです。

Rectangle Obj;

デフォルトのコンストラクターを呼び出します。その後、次を使用してメンバーを設定できます

Obj.Set(3, 5);
24
arne

そして、私はそのようなオブジェクトを明確にします:

Rectangle *Obj;

間違っていますが、これはオブジェクトではなくpointerを宣言しています。ポインターは、newを使用するか、既存のオブジェクトのアドレスを割り当てて初期化する必要があります。

8
Björn Pollex

うーん、少し混乱しています:

コンパイラーは実行時に表示します:変数 'Obj'は初期化されずに使用されています

それがあなたが呼ぶものですコンパイル時間。専門用語をまっすぐに伸ばします。

また、最も簡単な方法は

Rectangle Obj;
Obj.Set(3,5);

これは、動的割り当てまたはポリモーフィックコンテナを除く、ほとんどのシナリオで十分です。

std::vector<Shape*> v;
v.Push_back(new Rectange());
v.back()->Set(3,5);

v.Push_back(new Circle());
v.back()->Set(3,5);

//

newを使用するときはいつでもですが、deleteも忘れないでください。これは非常に悪夢のようです(例外の観点からも)。私は提案します:

std::vector<std::shared_ptr<Shape*> > v;
v.Push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);

v.Push_back(std::make_shared<Circle>());
v.back()->Set(3,5);
4
sehe

newのないポインタは、メモリのないものを宣言しています.. SO u u with new with pointerを使用する必要があります。ただし、Rectangle rect;はデフォルトでメモリを割り当てます。

これを確認するには、次のようなRectangleクラスのコンストラクタを作成します。

void Rectangle
{
  cout<<"Rectangle Constructor";
}

その後、メインで

Rectangle *rect; -->>O/P  -- "Nothing"
Rectangle rect2; -->>O/P  -- Rectangle Constructor
rect=new Rectangle; -->>O/P  -- Rectangle Constructor
3
Subhranshu

Rectangle *Obj;、Rectangleへのポインターを宣言していますが、ObjがどのRectangleを指すべきかを指定していません。後で既存のObjRectangleを設定またはインスタンス化するか、必要な場合にのみ使用します。

C++では、メモリとパフォーマンスを正確に制御できます。実際、それが一部の組み込み環境で使用されている理由です! Objを自動的にインスタンス化すると、いくつかの「問題」が発生します

  • いつObjを解放しますか?
  • 誰がObjを解放しますか?
  • ヒープにRectangleを作成することのパフォーマンスへの影響はどうですか?
  • これは、Rectangleを作成するのに十分なリソース(メモリ、CPUなど)が存在する環境ですか(特に大きい場合)。
  • Objのアドレスをどこかに渡し、静的に分析できない複雑な方法で実行時にインスタンス化しますか?

あなたがすることは構文エラーではありません。それはコンパイラがエラーを投げかけるものです-コンパイル時のエラーです。アナライザー(1つはVisual Studio 2010 Professionalに組み込まれています)は、初期化されていない変数を使用していることを警告する場合がありますが、これはオプションであり、有効にする必要がある場合があります。

3
foxy

コンパイラがコンパイル時にエラーを表示しないのはなぜですか?

なぜなら、それは構文的に正しいだからです。ただし、このようなステートメントは未定義の動作につながるため、スマートコンパイラは常に警告を発行します。

G ++では、この種のコンパイラ警告をエラーに変えることができます。

2
iammilind