- ベストアンサー
変数を式として指定することはできますか?
- 「new 式」で変数を式として指定することはできるかどうかについて疑問があります。具体的には、変数の内容に応じてclassAまたはclassBをnewするようなことをしたい場合に、簡潔な方法はないかと考えています。
- クラスの多様なインスタンスを簡潔に生成する方法について検討しています。現在はクラスごとにnew演算子を使用してインスタンスを生成していますが、もっとシンプルな方法があるのではないかと考えています。
- 変数を式として使用し、その内容によってclassAまたはclassBをnewする方法を知りたいです。forループを使用して複数のインスタンスを生成する際に、より効率的な方法を模索しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
VS2008(VC++9)だとfunction,lambda,arrayが使えないので代わりにこんなかんじ: #include <iostream> #include <map> #include <string> using namespace std; class base { public: virtual void hello() const =0; }; class classA : public base { void hello() const { cout << "classA\n"; }}; class classB : public base { void hello() const { cout << "classB\n"; }}; class classC : public base { void hello() const { cout << "classC\n"; }}; class classD : public base { void hello() const { cout << "classD\n"; }}; base* makeA() { return new classA; } base* makeB() { return new classB; } base* makeC() { return new classC; } base* makeD() { return new classD; } int main(){ typedef base* (*createfn)(); map<string,createfn> factory; factory["classA"] = &makeA; factory["classB"] = &makeB; factory["classC"] = &makeC; factory["classD"] = &makeD; const char* names[] = { "classA", "classB", "classC", "classD" }; for ( int i = 0; i < 4; ++i ) { base* p = factory[names[i]](); // 名前からクラスを生成 p->hello(); delete p; } }
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
結局のところ「まとめてしまう」と (プログラムの字面上) base へのポインタにしかならないので, 派生クラスへのポインタにしようとしたらダウンキャストが必要になります. 仮想関数があるなら dynamic_cast が安全かな. ただ, まとめる一方で「派生クラスに独自のメソッドがある」状況が適切なのかどうかはちょっと不明です. しょうがないこともあるけど, 「不自然な処理をしている」という可能性もないわけではないです.
- Tacosan
- ベストアンサー率23% (3656/15482)
ん~, p[n] = new cl[n]; 書くとして, p の型はどうするつもりなんだろう. オブジェクト指向的には class base { virtual base *create() = 0; }; class classA : public base { classA *create() { new classA; } }; (以下略) として base *p = anObject->create(); というのがよくある?
補足
回答ありがとうございます。 生成済みのInstanceから子を産ませるという方法でしょうか。 この質問ですこし考えたのですが、create()したものをbase のpointerに入れてもclassAなどの独自methodにはアクセス できないので、同じ派生クラスのポインタに代入できるような 方法を勉強してみたいと思います。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
うーん...やれなくはないけどエレガントじゃありませんよ。 #include <iostream> #include <map> #include <functional> #include <string> #include <array> using namespace std; class base { public: virtual void hello() const =0; }; class classA : public base { void hello() const { cout << "classA\n"; }}; class classB : public base { void hello() const { cout << "classB\n"; }}; class classC : public base { void hello() const { cout << "classC\n"; }}; class classD : public base { void hello() const { cout << "classD\n"; }}; int main(){ map<string,function<base*()>> factory; factory["classA"] = [](){return new classA;}; factory["classB"] = [](){return new classB;}; factory["classC"] = [](){return new classC;}; factory["classD"] = [](){return new classD;}; array<string,4> names = { "classA", "classB", "classC", "classD" }; for ( int i = 0; i < 4; ++i ) { base* p = factory[names[i]](); // 名前からクラスを生成 p->hello(); delete p; } } # Visual Studio 2010 (VC++10) で動作確認済
補足
回答、ありがとうございます。 VC++2008 Exp で compile すると次の Errorが出ます。 'function' : 定義されていない識別子です。 対応方法を教えていただけますでしょうか。 よろしくお願いします。
お礼
回答、ありがとうございます。 最初のListは理解できなかったのですが、今回のは良く分かりました. newしたobjectのポインタを同じクラスのポインタに代入する方法を 含めて勉強してみます。