インスタンス化せずにC ++で変数を宣言することは可能ですか? 私はこのようなことをしたい:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
基本的に、条件の外側を宣言して、適切なスコープを取得したいだけです。
ポインターを使用せずa
にヒープに割り当てる方法はありますか? 多分参照で賢い何か?
インスタンス化せずにC ++で変数を宣言することは可能ですか? 私はこのようなことをしたい:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
基本的に、条件の外側を宣言して、適切なスコープを取得したいだけです。
ポインターを使用せずa
にヒープに割り当てる方法はありますか? 多分参照で賢い何か?
コンストラクターを呼び出さずに変数を宣言することはできません。ただし、あなたの例では、次のことができます。
Animal a(happyDay() ? "puppies" : "toads");
ここで参照を使用することはできません。スコープから出るとすぐに、参照は削除されるオブジェクトを指すことになるからです。
実際、ここには 2 つの選択肢があります。
1-ポインターを使用します:
Animal* a;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
// ...
delete a;
またはスマートポインターを使用して
#include <memory>
std::unique_ptr<Animal> a;
if( happyDay() )
a = std::make_unique<Animal>( "puppies" );
else
a = std::make_unique<Animal>( "toads" );
2- Init メソッドを に追加しAnimal
ます。
class Animal
{
public:
Animal(){}
void Init( const std::string& type )
{
m_type = type;
}
private:
std:string m_type;
};
Animal a;
if( happyDay() )
a.Init( "puppies" );
else
a.Init( "toads" );
私は個人的にオプション2を使用します。
デフォルトのコンストラクターでオブジェクトを定義するとオブジェクトが構築されるため、これを C++ で直接行うことはできません。
ただし、最初にパラメーター化されたコンストラクターを実行できます。
Animal a(getAppropriateString());
または、実際に のようなものを使用して?: operator
、正しい文字列を決定することもできます。(更新:@Gregはこれの構文を提供しました。その回答を参照してください)
私はグレッグの答えを好みますが、これを行うこともできます:
char *AnimalType;
if( happyDay() )
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
条件演算子が禁止されている場所で働いたことがあるので、これをお勧めします。(ため息!) また、これは非常に簡単に 2 つの選択肢を超えて拡張できます。
ガベージ コレクションを回避したい場合は、スマート ポインターを使用できます。
auto_ptr<Animal> p_a;
if ( happyDay() )
p_a.reset(new Animal( "puppies" ) );
else
p_a.reset(new Animal( "toads" ) );
// do stuff with p_a-> whatever. When p_a goes out of scope, it's deleted.
それでも使いたい場合は. -> の代わりに構文を使用する場合は、上記のコードの後にこれを実行できます。
Animal& a = *p_a;
// do stuff with a. whatever
std::move も使用できます。
class Ball {
private:
// This is initialized, but not as needed
sf::Sprite ball;
public:
Ball() {
texture.loadFromFile("ball.png");
// This is a local object, not the same as the class member.
sf::Sprite ball2(texture);
// move it
this->ball=std::move(ball2);
}
...
はい、次のことができます。
Animal a;
if( happyDay() )
a = Animal( "puppies" );
else
a = Animal( "toads" );
これにより、コンストラクターが適切に呼び出されます。
編集:1つ忘れていました... aを宣言するときは、何もしないコンストラクターであるか、値を初期化するコンストラクターであるかにかかわらず、コンストラクターを呼び出す必要があります。したがって、このメソッドは 2 つのオブジェクトを作成します。1 つは初期化時、もう 1 つは if ステートメント内です。
より良い方法は、次のようなクラスの init() 関数を作成することです。
Animal a;
if( happyDay() )
a.init( "puppies" );
else
a.init( "toads" );
この方法はより効率的です。