アプリ版:「スタンプのみでお礼する」機能のリリースについて

あるクラスのインスタンスが動的に複数生成される状態で,一つのインスタンスから,
複数の他インスタンスのメンバ関数(仮に関数A)を呼びたいと考えています.
そこでstaticなインスタンスのリストのようなものを設けようと考えました.

各インスタンスの関数Aへ関数ポインタの配列を定義し,
それによって上記を実現しようと思いました.

しかし,インスタンス生成前にインスタンス名を指定して
(instance_name_.*p)();
という様に呼べるわけもなく,どう動的にインスタンスのリストを保持するかが思いつきません.

説明が下手ですいません.どなたか教えていただけますでしょうか.
よろしくお願いします.

環境
Windows XP, cygwin

A 回答 (2件)

 こんにちは。


 初期作成はstaticメンバ関数で行って、その後出来あがったインスタンスのCloneメンバ関数を呼び出して増殖する、と言うのは。

#include<memory>
#include<map>
#include<vector>
#include<string>
#include<iostream>

class II;

typedef std::tr1::shared_ptr<II> IIPtr;

class II
{
typedef IIPtr(*PFNCREATE)();
typedef std::map<std::string, PFNCREATE> IIMap;
static IIMap* _S_pMap;
static const int _S_init;
static void Exit()
{
delete _S_pMap;
}
static IIMap& MapRef()
{
if(_S_pMap == NULL)
_S_pMap = new IIMap();
return *_S_pMap;
}
public:
static bool Append(const std::string& name, PFNCREATE pfn)
{
IIMap& rMap = MapRef();
return rMap.insert(std::make_pair(name, pfn)).second;
}
static IIPtr Create(const std::string& name)
{
IIMap& rMap = MapRef();
IIMap::iterator it = rMap.find(name);
return it != rMap.end() ? (*it->second)() : IIPtr();
}
II(){}
virtual ~II(){}
virtual void Print() = NULL;
virtual IIPtr Clone() const = NULL;
};

II::IIMap* II::_S_pMap = NULL;
const int II::_S_init = ::atexit(&II::Exit);

class AA : public II
{
static const bool _S_init;
static IIPtr Create(){return IIPtr(new AA());}
public:
AA(){}
virtual ~AA(){}
virtual void Print(){std::cout << "AA" << std::endl;}
virtual IIPtr Clone() const { return IIPtr(new AA());}
};

const bool AA::_S_init = II::Append("AA", &AA::Create);

class BB : public II
{
static const bool _S_init;
static IIPtr Create(){return IIPtr(new BB());}
public:
BB(){}
virtual ~BB(){}
virtual void Print(){std::cout << "BB" << std::endl;}
virtual IIPtr Clone() const { return IIPtr(new BB());}
};

const bool BB::_S_init = II::Append("BB", &BB::Create);

int main()
{
std::vector<IIPtr> v;
v.push_back(II::Create("AA"));
v.push_back(II::Create("BB"));

for(std::size_t n = 0; n < v.size(); ++n)
v[n]->Print();

IIPtr pa = v[0]->Clone();
IIPtr pb = v[1]->Clone();

pa->Print();
pb->Print();

return 0;
}
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます.
しかもプログラムまで・・・.
今頑張ってコードを読んでます!!
追加するのも関数化した方が後々分かりやすいかもと思いました.

お礼日時:2010/01/14 09:06

コンストラクタの中か、インスタンス生成後にリストに追加すれば?


#include <iostream>
#include <string>
#include <iterator>
#include <list>
using namespace std;


class Test;
static list<Test *> test_list;

class Test {
public:
  Test(char *str) {
    this->str = string(str);
    test_list.push_back(this);
  }
  void a() {
    cout << str << endl;
  }
private:
  string str;
};

int main(void)
{
  Test test1("ABC");
  Test test2("DEF");
  Test *test_ptr;

  list<Test *>::iterator it = test_list.begin();
  while(it != test_list.end()) {
    test_ptr = *it;
    test_ptr->a();
    it++;
  }

  return 0;
}
    • good
    • 0
この回答へのお礼

ご返答ありがとうございます!

ポインタの配列とかにしないで,listを使えばよかったんですね.
C++に疎く,listやらmapやらあるのを知りませんでした・・・.

お礼日時:2010/01/14 09:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!