c++ - 通过存储指向成员函数的指针的虚拟行为

标签 c++

为什么要阻止虚拟行为?

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;
          }
     } 

最佳答案

这里是这一行:

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

尝试将其替换为

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

发生的事情叫做slicing ,即使您可能传入了 MyClass 的子类,当您调用 Process 时,也会使用 MyCLass 的复制构造函数在堆栈上创建一个新的 MyClass 对象。这个新对象在任何方面都是一个 MyClass,包括拥有 MyClass 的虚拟表。

当您通过引用或指针传递时,不会进行任何复制,并且对 MyClass 的引用可以引用一个真正属于 SubClassOfMyClass 类型的对象。

编辑:

好吧,问题出在许多编译错误中的一个,如果你得到所有这些来编译它就可以正常工作:

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");
}

哪些输出:

Command=X, and result=1

关于c++ - 通过存储指向成员函数的指针的虚拟行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/643317/

相关文章:

c++ - 类型 'double*' 和 'double' 到二进制 'operator+' 的无效操作数

javascript - 如何检测故障并重置/重启 webassembly 模块?

c++ - 尝试使用带有数组的数据结构来制作程序

c++ - QMutexLocker 是否返回错误代码(如果有)?

c++ - 字典顺序的定义?

c++ - 未在范围内声明的类

c# - 如何使用 P/INVOKE 将 C++ char* 编码为 C# 字符串

当类成员隐藏其父类的类成员时,C++ 会生成警告吗?

c++ - 寻找一种安全、便携的密码存储方法

c++ - 尝试使用 lua 错误调用对象方法时 luabind 中止