クラス(not インスタンス)を関数に渡すには? – プログラミング – Home

クラス(not インスタンス)を関数に...
 
通知
すべてクリア

クラス(not インスタンス)を関数に渡すには?


おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

識者の方教えてください。

.net2003 MFCです。

ある関数内で、CDialogクラスの派生クラスを生成したいのですが、
呼ぶたびにクラスは異なります。
今は関数を呼ぶ前にnewしてるのですが、
以下のようなことができればベターです。
しかし、やはり無理なのでしょうか?

他にいい代替案があればお願いします。

void Kansu( クラスのインスタンスではなく、クラス名をパラメータとして渡したい )
{
派生クラス pDlg = new 派生クラス;
pDlg->Create( this );
}


引用解決済
トピックタグ
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

リソースIDがいりますね。

void Kansu( クラス名, INT iIDD )
{
派生クラス pDlg = new 派生クラス;
pDlg->Create( iIDD, this );
}

今は、

void Kansu( CDialog* pDlg, INT iIDD )
{
pDlg->Create( iIDD, this );
}

として、

CDlg××* pDlg = new CDlg××;
Kansu( pDlg, IDD××);

としてます。


返信引用
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

そのクラス名は、コンパイル時点で定められますか?

コンパイル時点で確定できるなら、template が使えませんか?
実行時だと無理です。

#include <iostream>
#include <string>

template<class T>
class Base
{
public:
void kansu()
{
T* pT = static_cast<T*>(this);
pT->CallMethod();
}
};

class DeriveA : public Base<DeriveA>
{
public:
void CallMethod()
{
std::cout << A::CallMethod() called.\n;
}
};

class DeriveB : public Base<DeriveB>
{
public:
void CallMethod()
{
std::cout << B::CallMethod() called.\n;
}
};

class Driver
{
public:
template<class T>
void test(Base<T>* pT)
{
pT->kansu();
}
};

int main(void)
{
DeriveA a;
DeriveB b;
Driver d;

d.test(&a);
d.test(&b);

return 0;
}


返信引用
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

# どこかで見たと思ったら

クラス名から動的にオブジェクトを作成
http://forums.belution.com/ja/cpp/000/048/96s.shtml


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

ありがとうございます。
ちょっと理解に時間がかかりそうですが、
勉強してみます。


返信引用
reshia
 reshia
(@reshia)
ゲスト
結合: 20年前
投稿: 117
 

こんな↓でよければ、どうぞ。

//---------------------------------
#include <iostream>
#include <string>

class Super {
public:
Super() {}
~Super() {}
public:
virtual const char* run()=0;
};

class SubA : public Super {
public:
SubA() : Super() {}
~SubA() {}
static const char* GetName() {
return SubA;
}
virtual const char* run() {
return SubA;
}
};

class SubB : public Super {
public:
SubB() : Super() {}
~SubB() {}
static const char* GetName() {
return SubB;
}
virtual const char* run() {
return SubB;
}
};

Super* GetInstance(std::string name) {
if (name == SubA::GetName() ) {
return new SubA();
} else if (name == SubB::GetName() ) {
return new SubB();
}
return 0;
}

int main(int argc, char* argv[])
{
using namespace std;

Super* instance;
instance = GetInstance( string(SubA) );

cout << instance name is \";
cout << ((instance != 0) ? instance->run() : null) << \" << endl;

delete instance;
return 0;
}
//---------------------------------

ってこともできますけど。
もう少し、スマートにすると、

//---------------------------------
#include <iostream>
#include <string>

class Super {
public:
Super() {}
~Super() {}
public:
virtual const char* run() =0;
};

class SubA : public Super {
public:
SubA() : Super() {}
~SubA() {}
static const char* GetName() {
return SubA;
}
virtual const char* run() {
return SubA;
}
};

class SubB : public Super {
public:
SubB() : Super() {}
~SubB() {}
static const char* GetName() {
return SubB;
}
virtual const char* run() {
return SubB;
}
};

class InstanceManager {
private:
Super* instance;
public:
InstanceManager() : instance(0) {}
~InstanceManager() {
if (instance != 0) {
delete instance;
}
}
Super* const GetInstance(std::string name) {
if (instance != 0) {
delete instance;
instance = 0;
}

if (name == SubA::GetName() ) {
instance = new SubA();
} else if (name == SubB::GetName() ) {
instance = new SubB();
}

return instance;
}
Super* const GetInstance() {
return instance;
}
};

int main(int argc, char* argv[])
{
using namespace std;

InstanceManager im;

Super* instance = im.GetInstance(SubA);

cout << instance name is \" << ((instance != 0) ? instance->run
() : null) << \" << endl;
return 0;
}
//---------------------------------

かと。。
こんなでどうでしょうか。

ま、子クラスが増えると、GetInstanceのif-elseを
書き直す必要があるので、汚いですけど。。
#ま、子クラスが乱立している状況も汚いですけど。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

> static const char* GetName() {

単一コンパイラでかまわないなら、typeid という手も。

で、サブクラスの実装は template 化してみる。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました