2011-12-17 18 views
19

デフォルトのコンストラクターや代入演算子を持たないクラスがあるため、別の関数の結果に応じてif/elseステートメント内で宣言され、初期化されます。しかし、それは条件の両方のルートがインスタンスを作成するにもかかわらず、後で範囲外であると言います。ifステートメントの変数の範囲

は(ちょうどポイントを説明するためにintで行われる)次の例を考えてみましょう:

#include <iostream> 

int main() 
{ 
    if(1) { 
    int i = 5; 
    } else { 
    int i = 0; 
    } 

    std::cout << i << std::endl; 
    return 0; 
} 

は、条件付きの終わりに範囲外の条件、外出先で宣言された変数ですか?デフォルトのコンストラクタは存在しないが、コンストラクタの引数は特定の条件に依存する状況を処理する正しい方法は何ですか?

編集

与えられた回答の光で、事態はそうかもしれないアプローチが変化しなければならない、より複雑です。 Aから派生した抽象基本クラスAと2つのクラスBとCがあります。どのようにすればこのようになりますか:

if(condition) { 
    B obj(args); 
} else { 
    C obj(args); 
} 

アプローチを変更しますか? Aは抽象型なので、A* objを宣言し、newで適切な型を作成するだけではありません。

+0

あなたの継承は仮想か静的ですか? – Dani

+0

バーチャル、そう思う。 'class A'は仮想関数を持っています(C++は私の強い訴えではありませんが、私はFortranでよく働きます) – tpg2114

+0

あなたは実際に抽象クラスへのポインタを宣言できます。 –

答えて

16

"条件文で宣言されたDo変数は、条件文の最後に範囲外になりますか?"

はい - ローカル変数のスコープでのみ囲む括弧内にある:あなたのケースでは

{ 
    int x; //scope begins 

    //... 
}//scope ends 
//x is not available here 

を、あなたはclass Aを持っていると言います。

A a = condition ? A(1) : A(2,3); 

あなたは、ヒープ上のインスタンスを作成している場合:あなたは別のコンストラクタのプロトタイプを使用している場合

A a(condition ? 1 : 2); 

のか:

あなたはポインタを扱っていない場合

A* instance = NULL; 
if (condition = true) 
{ 
    instance = new A(1); 
} 
else 
{ 
    instance = new A(2); 
} 

または3者演算子を使用できます。

//if condition is true, call A(1), otherwise A(2) 
A* instance = new A(condition ? 1 : 2); 

EDIT:

はい、できます

A* x = NULL; //pointer to abstract class - it works 
if (condition) 
    x = new B(); 
else 
    x = new C(); 

EDIT:

工場出荷時のパターンが何であるか、あなたが探しているようだ(それを見て):

class A; //abstract 
class B : public A; 
class C : public A; 

class AFactory 
{ 
public: 
    A* create(int x) 
    { 
     if (x == 0) 
      return new B; 
     if (x == 1) 
      return new C; 
     return NULL; 
    } 
}; 
+0

この場合、メモリは再割り当てされますか?可変スコープが囲む{}の後に終了した後。 – kaushalpranav

4

Do変数条件付きで宣言された範囲外の範囲外に行く 条件付き?

はい。

そこには デフォルトコンストラクタがありませんが、コンストラクタの引数が 特定の条件文に依存状況を処理するための正しい方法は何ですか?

コピーする値を返す関数を作成します。

T foo() 
{ 
    if(condition) 
     return T(x); 
    return T(y); 
} 

void bar() 
{ 
    T i(foo()); 
} 

編集:Aは抽象的なので、私はちょうど* OBJを宣言し、新しいと 適切なタイプを作成することができませんでした

どういう意味ですか?それはまさに動的なタイピングの仕組みです。私は生のポインタを使用しないことを除いて、私はunique_ptrを使用します。

std::unique_ptr<A> obj; 
if(condition) { 
    obj = std::unique_ptr<A>(new B(args)); 
} else { 
    obj = std::unique_ptr<A>(new C(args)); 
} 
+0

この回答は最初の回答と矛盾していますか? (条件付きで宣言された変数が条件付きで終了するかどうかについて) – LazerSharks

+1

@Gnuey:そうではありません。ルチアンがどの質問に「いいえ」と回答しているのかは分かりません。おそらく、彼はちょうど質問を読んだときと答えを書いたときの間に、言葉が混乱しているかもしれません。しかし、完全なステートメントとそれに続くコメント付きのコードスニペットは、私の答えにはっきりと同意します。 –

0

はい条件付きのループなどで宣言されていると範囲外になります。条件の種類によって変数のタイプが変わるのでしょうか?

+0

だから両方の場合があります。条件付きであろうとなかろうと同じタイプであることもありますが、条件付きで異なるタイプになることもあります。どのようにアプローチが2つの状況のた​​めに変わるでしょうか? – tpg2114

+0

@ tpg2114あなたは私の答えをお読みになりましたか? –

+0

私は持っています。私はそれが最初のケース(同じタイプ)にどのように対処するかを見ています。それは、条件付きに基づいて宣言されている異なるタイプの可能性にどのように対処していますか? – tpg2114

0

あなたの代わりになりますポインター:

MyObject *obj; 
if(cond1) 
{ 
    obj = new MyObject(1, 2, 3); 
} 
else 
{ 
    obj = new MyObject(4, 5); 
} 

あなたがそれで行われ、またはスマートポインタを使用しているときにそれを削除することを忘れないでください。

+0

あなたは**ポインタを使うことができますが、そうする必要はありません。 –