解決済みの質問
「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
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
1人が「このQ&Aが役に立った」と投票しています
ベストアンサー以外の回答(3件中 1~3件目)
ん~,
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
うーん...やれなくはないけどエレガントじゃありませんよ。
#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