デフォルトのコンストラクターや代入演算子がないクラスがあるので、別の関数の結果に応じて、if/elseステートメント内で宣言および初期化されます。しかし、条件付きの両方のルートがインスタンスを作成する場合でも、それは後でスコープ外になると述べています。
次の例を考えてみましょう(要点を説明するために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
で適切な型を作成することはできませんでした。
「条件付きで宣言された変数は、条件付きの最後でスコープ外になりますか?」
はい-ローカル変数のスコープは、括弧で囲まれているだけです。
{
int x; //scope begins
//...
}//scope ends
//x is not available here
あなたの場合、あなたはclass A
。
ポインタを扱っていない場合:
A a( condition ? 1 : 2 );
または、別のコンストラクタプロトタイプを使用している場合:
A a = condition ? A(1) : A(2,3);
ヒープ上にインスタンスを作成している場合:
A* instance = NULL;
if ( condition )
{
instance = new A(1);
}
else
{
instance = new A(2);
}
または、三項演算子を使用できます。
//if condition is true, call A(1), otherwise A(2)
A* instance = new A( condition ? 1 : 2 );
編集:
はい、できます:
A* x = NULL; //pointer to abstract class - it works
if ( condition )
x = new B();
else
x = new C();
編集:
あなたが探しているのはファクトリーパターンです(それを調べてください):
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;
}
};
条件で宣言された変数は、条件の最後でスコープ外になりますか?
はい。
デフォルトのコンストラクタはないが、コンストラクタの引数が特定の条件に依存する状況を処理する正しい方法は何ですか?
コピー元の値を返す関数を記述します。
T foo()
{
if(condition)
return T(x);
return T(y);
}
void bar()
{
T i(foo());
}
編集:
Aは抽象なので、A * objを宣言してnewで適切な型を作成することはできませんでした。
どういう意味ですか?これがまさに動的型付けの仕組みです。生のポインタを使用しない場合を除いて、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));
}
はい、条件、ループなどで宣言された場合、スコープ外になります。条件によって変数の型は変わりますか?
あなたの代わりはポインタです:
MyObject *obj;
if(cond1)
{
obj = new MyObject(1, 2, 3);
}
else
{
obj = new MyObject(4, 5);
}
使い終わったら必ず削除するか、スマートポインタを使用してください。