0

编辑从代码本身中删除格式(粗体)。

编辑 2在答案末尾添加了修复

我有以下代码,我试图在其中创建静态多态性和模板类,我试图在只有一个派生类型成员函数 ptr中插入映射。地图的定义是这样的:

std::map<std::string,void(derived::*)()> m_func;

插入命令是这样的:

`m_func.insert(make_pair("yaodav",&derived::HelloWorld));`

这是整个代码:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <any>
#include <typeinfo>
#include <typeindex>
using namespace std;


template<class Derived>
class base
{
public:
    void clean()
    {
        cout << "I'm cleannig \n";
    }
    void process()
    {
        static_cast<Derived*>(this)->setup();
        static_cast<Derived*>(this)->run();
        static_cast<Derived*>(this)->cleanup();
    }
};


class derived : public  base<derived> 
{
    friend class base<derived>;
    void setup() {
        m_func.insert(make_pair("yaodav",&derived::HelloWorld));
        cout << "derived setup \n"; }
    void run() { cout << "derived run \n"; }
    void cleanup() { cout << "derived cleanup \n"; }
    void HelloWorld() {cout << "hwllo from derived \n"; }
    std::map<std::string,void(derived::*)()> m_func;

};


class derived1 : public base<derived1> 
{
    friend class base<derived1>;
    void setup() {cout << "derived1 setup \n"; }
    void run() { cout << "derived1 run \n"; }
    void cleanup() { cout << "derived1 cleanup \n"; }
    void HelloWorld(){}
};

template <class T>
class Y{
 public:
 std::vector<std::any> m_vec;   

};


template <typename T>
class D:public Y<T>
{
    public:
    friend class Y<T>;
    void print()
    {
        for(auto& e: Y<T>::m_vec)
        {
             if(e.type()==typeid(base<derived1>*))
            {
                try {
                    auto* r = any_cast<base<derived1>*>(e);
                    r->process();
                }
                catch(const std::bad_any_cast& e) {
                    std::cout << e.what() << '\n';
                }
            }
            else
            {
                try {
                    auto *r = any_cast<base<derived> *>(e);
                    r->process();
                }
                catch(const std::bad_any_cast& e) {
                    std::cout << e.what() << '\n';
                }
            }

        }
    } 
};


int main()
{
        base<derived>* b =  new base<derived>;
        base<derived1>* c =  new base<derived1>;

        D<derived> y;
        y.m_vec.push_back(b);
        y.m_vec.push_back(c);
        y.print();
}

但是当调用插入函数(粗体部分)时,我遇到了分段错误,这就像我运行调试器时 m_func 不存在并且我不会打印我得到的 m_func :

这里没有名为 m_func 的成员或方法

为什么会发生这种情况以及如何解决它

修复

 base<derived>* b =  new derived;
 base<derived1>* c =  new derived1;

代替

 base<derived>* b =  new base<derived>;
 base<derived1>* c =  new <derived1>;
4

1 回答 1

0

您的代码大致相当于:

base<derived>* b = new base<derived>;
b->process();

在里面process,有static_cast<Derived*>(this)- 但指向的实例base<derived>实际上不是. 您已经独立实例化,而不是作为实例的一部分。您的程序从未创建, nor的实例。所以你试图调用一个从未存在过的对象的成员函数,因此你的程序表现出未定义的行为。bderivedbase<derived>derivedderivedderived1


更精简的代码版本如下所示:

class Base{};
class Derived : public Base {
public:
  void DoSomething() {};
};

int main() {
  Base* b = new Base;
  static_cast<Derived*>(b)->DoSomethind();  // undefined behavior here
}

这样,应该更清楚出了什么问题。

于 2019-10-24T21:08:17.027 回答