tags:

views:

112

answers:

3

Why is virtual behavior being prevented?

class  MyClass
    {
       //........
       virtual double GetX();
       virtual double GetSomethingElse();
       virtual double GetT();
       virtual double GetRR();
       //........

    };

    class Processor
    {
     private:
          typedef double (MyClass::*MemFuncGetter)();
          static map<std::string, MemFuncGetter> descrToFuncMap;

     public:
            static void Initialize();
            void Process(Myclass m, string);

    };

    void Processor::Initialize()
    {

         descrToFuncMap["X"]=&MyClass::GetX;
         descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse;
         descrToFuncMap["RR"]=&MyClass::GetRR;
         descrToFuncMap["T"]=&MyClass::GetT;
    };

    void Processor::Process(MyClass *ms, const std::string& key)
    {
         map<std::string, Getter>::iterator found=descrToFuncMap.find(key);
         if(found!=descrToFuncMap.end())
         {
            MemFuncGetter memFunc=found->second;
            double dResult=(ms).*memFunc();
            std::cout<<"Command="<<key<<", and result="<<result<<std::end;
          }
     }
+7  A: 

This line here:

void Processor::Process(MyClass ms, const std::string& key)

Try replacing it with

void Processor::Process(MyClass &ms, const std::string& key)

What is happening is called slicing, even though you may have passed in a sub-class of MyClass, when you call Process, a new MyClass object is made on the stack using MyCLass's copy-constructor. This new object is a MyClass in everyway, including having MyClass's virtual table.

When you pass by reference, or with a pointer, no copy is made, and the reference to MyClass can be refering to an object that is really of a type SubClassOfMyClass.

Edit:

Well, the issue is with one of the many compile errors, if you get this all to compile it works just fine:

class  MyClass
{
public:
   //........
   virtual double GetX() { return 0.0; }
};

class  MyClass2 : public MyClass
{
public:
   //........
   virtual double GetX()  { return 1.0; }
};

class Processor
{
public:
   typedef double (MyClass::*MemFuncGetter)();
   static void Initialize();
   void Process(MyClass *m, const string &);
private:
   static map<std::string, MemFuncGetter> descrToFuncMap;
};

void Processor::Initialize()
{
     descrToFuncMap["X"]=&MyClass::GetX;
}

void Processor::Process(MyClass *ms, const std::string& key)
{
     map<std::string, MemFuncGetter>::iterator found=descrToFuncMap.find(key);
     if(found!=descrToFuncMap.end())
     {
        MemFuncGetter memFunc=found->second;
        double dResult=(ms->*memFunc)();
        std::cout<<"Command="<<key<<", and result="<<dResult<<std::endl;
      }
 }

map<std::string, Processor::MemFuncGetter> Processor::descrToFuncMap;

int main()
{
    Processor::Initialize();
    Processor p;

    MyClass2 mc2;
    p.Process(&mc2, "X");
}

Which outputs:

Command=X, and result=1

Eclipse
it is passed as a pointer -- no slicing
+1  A: 

Wow I have never seen a sample piece of code have so many other syntax errors before you get to the real problem.

When posting code it should be compilable by the people you want to help.
With the exception of the ONE bug you want others to help you with.

I am not sure what you are trying to achieve but it is not virtual functions. SO you should porobably re-name your question.

I presume your main problem is with this line:

MemFuncGetter memFunc=found->second;
double dResult=(ms).*memFunc();

Depending if you accepted Josh's advice the syntax should look like this.

 MemFuncGetter memFunc=found->second;
 double dResult=(ms.*memFunc)();    // MyClass& ms

 -- or

 double dResult=(ms->*memFunc)();   // MyClass* ms
Martin York
+1  A: 

Have you considered using boost::bind and boost::function? It allows you to bind pointers to free/member functions and allows you to bind specific parameters as well for deferred calling.

Here's a tutorial/example: http://www.codeproject.com/KB/library/BoostBindFunction.aspx

wchung
I did, but the company i work for, does NOT