「new 式」 で、変数を 式 として指定することはできますか?

解決済みの質問

「new 式」 で、変数を 式 として指定することはできますか?

「new 式」 で、変数を 式 として指定することはできますか?

例えば次のような感じで、変数clの内容によりclassAあるいはclassBをnew
するようなことがしたいです。
class base [ ... };
class classA : public base { .... };
class classB : public base { .... };
classA* ca;
classB* cb;
base* cl;
cl = classA;
ca = new cl;
cl = classB;
ca = new cl;

これにより、多種のclassをnewする際にいちいち
pa = new classA;
pb = new classB;
pc = new classC;
pd = new classD;
............
としないで、
for (n=0; n<xxx; n++)
p[n] = new cl[n];
…みたいに簡潔に書けないかなと考えてます。
よろしくお願いします。

投稿日時 - 2010-08-07 13:12:42

連想キーワード:

QNo.6092951

すぐに回答ほしいです

質問者が選んだベストアンサー

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;
}
}

投稿日時 - 2010-08-08 09:12:49

お礼

回答、ありがとうございます。
最初のListは理解できなかったのですが、今回のは良く分かりました.
newしたobjectのポインタを同じクラスのポインタに代入する方法を
含めて勉強してみます。

投稿日時 - 2010-08-08 10:28:28

ANo.3

1人が「このQ&Aが役に立った」と投票しています

[  前へ  |  次へ ]

ベストアンサー以外の回答(3件中 1~3件目)

ANo.4

結局のところ「まとめてしまう」と (プログラムの字面上) base へのポインタにしかならないので, 派生クラスへのポインタにしようとしたらダウンキャストが必要になります. 仮想関数があるなら dynamic_cast が安全かな.
ただ, まとめる一方で「派生クラスに独自のメソッドがある」状況が適切なのかどうかはちょっと不明です. しょうがないこともあるけど, 「不自然な処理をしている」という可能性もないわけではないです.

投稿日時 - 2010-08-11 13:46:18

ANo.2

ん~,
p[n] = new cl[n];
書くとして, p の型はどうするつもりなんだろう.
オブジェクト指向的には
class base { virtual base *create() = 0; };
class classA : public base { classA *create() { new classA; } };
(以下略)
として
base *p = anObject->create();
というのがよくある?

投稿日時 - 2010-08-07 23:55:12

補足

回答ありがとうございます。
生成済みのInstanceから子を産ませるという方法でしょうか。
この質問ですこし考えたのですが、create()したものをbase
のpointerに入れてもclassAなどの独自methodにはアクセス
できないので、同じ派生クラスのポインタに代入できるような
方法を勉強してみたいと思います。

投稿日時 - 2010-08-08 10:23:04

ANo.1

うーん...やれなくはないけどエレガントじゃありませんよ。

#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) で動作確認済

投稿日時 - 2010-08-07 14:02:24

補足

回答、ありがとうございます。
VC++2008 Exp で compile すると次の Errorが出ます。
    'function' : 定義されていない識別子です。
対応方法を教えていただけますでしょうか。
よろしくお願いします。

投稿日時 - 2010-08-08 03:55:05

あわせてチェックしたい
  • Rails AR 深い階層のテーブル参照 ...
  • 多種共存 ...
  • 配列であるメンバのコンストラクタを呼ぶ方法 ...
PR
【回答募集中】花粉にひと言、物申す![ 詳細 ]

OKWaveのオススメ

教えて弁護士さん!

お金の悩みQ&A特集はこちら