我想能夠調用一些具有相同通用語法和基類的不同類的成員函數。沿將函子映射到成員函數,丟失範圍
class A: public BaseClass
{
public:
A();
~A();
int DoFoo();
int DoBar();
int DoBarBar();
};
class B : public BaseClass
{
public:
B();
~B();
int DoSomething();
int DoSomethingElse();
int DoAnother();
};
線在那裏我可能會將來自兩類成員函數到一個地圖,這樣我可以有類似
key value
"Option1" *DoFoo()
"Option2" *DoSomething()
"Option3" *DoFoo()
... ...
"Option6" *DoAnother()
在那裏我可以調用一個函數返回一個值的東西基於我選擇的選項,無論該功能屬於哪個類別。
通過一些搜索,我試圖實現我自己映射的仿函數集。但是,映射保留了函子的地址,但其中的函數變爲空。
這裏是存儲類對象和函數指針我的仿函數聲明
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
//////////////////////////////////////////////////////////////
//Functor Classes
//////////////////////////////////////////////////////////////
class TFunctor
{
public:
virtual void operator()()=0; // call using operator
virtual int Call()=0; // call using function
};
// derived template class
template <class TClass> class TSpecificFunctor : public TFunctor
{
private:
int (TClass::*fpt)(); // pointer to member function
TClass* pt2Object; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
TSpecificFunctor(TClass* _pt2Object, int(TClass::*_fpt)())
{ pt2Object = _pt2Object; fpt=_fpt; };
// override operator "()"
virtual void operator()()
{ (*pt2Object.*fpt)();}; // execute member function
// override function "Call"
virtual int Call()
{return (*pt2Object.*fpt)();}; // execute member function
};
typedef std::map<std::string, TFunctor*> TestMap;
//////////////////////////////////////////////////////////////
//Test Classes
//////////////////////////////////////////////////////////////
//Base Test class
class base
{
public:
base(int length, int width){m_length = length; m_width = width;}
virtual ~base(){}
int area(){return m_length*m_width;}
int m_length;
int m_width;
};
//Inherited class which contains two functions I would like to point to
class inherit:public base
{
public:
inherit(int length, int width, int height);
~inherit();
int volume(){return base::area()*m_height;}
int area2(){return m_width*m_height;}
int m_height;
TestMap m_map;
};
在我的繼承類的構造函數的樣子:
inherit::inherit(int length, int width, int height):base(length, width)
{
m_height = height;
TSpecificFunctor<inherit> funcA(this, &inherit::volume);
m_map["a"] = &funcA;
TSpecificFunctor<inherit> funcB(this, &inherit::area2);
m_map["b"] = &funcB;
}
這是我在哪裏映射兩種功能成地圖。在內存地址和函數指針方面,上述函數中的東西仍然看起來不錯。
然後我嘗試在一個新的類來創建繼承的實例...
class overall
{
public:
overall();
~overall(){}
inherit *m_inherit;
TestMap m_mapOverall;
};
overall::overall()
{
m_inherit = new inherit(3,4,5);
TestMap tempMap = m_inherit->m_map;
int i = 0;
}
在這裏,當我看着m_inherit-> m_map的價值觀,我注意到,密鑰仍然一致,但是我試圖指出的功能的內存地址已經消失。
我對函子沒有太多的經驗,但從我的理解來看,它能夠保留狀態,我認爲這意味着我可以在類之外調用成員函數。但我開始認爲我的成員函數因爲超出範圍而消失。
+1對於lambda表達式的引用,儘管它也許值得一提的是'std :: function',因爲這將是創建這些的'std :: map'的最簡單方法。 – Fraser 2012-07-11 01:06:50
@Fraser謝謝,好主意。我已經爲lambdas添加了一個小例子。 – 2012-07-11 01:22:50
不錯的一個。 (順便說一下,這裏的每個lambda都不需要'() - > int') – Fraser 2012-07-11 02:01:31