首页 > 解决方案 > 试图将基类函数指针指向派生类函数

问题描述

我正在尝试实施一种策略模式。现在我正在制作一个函数指针向量,它接受一个整数向量作为它们的类型。我把这个函数指针向量称为“算法”。我希望向量中的每个函数指针都指向不同的排序类(合并、冒泡或插入)。我的类结构是这样的:Algorithm是基类,Sort是继承自Algorithm的抽象类,然后Merger、Insertion、Bubble都继承自Sort。我现在遇到的问题是我似乎无法让我的 mergePointer 指向sortFunc()Merger 类的内部。当我尝试执行我的代码时,它说:

main.cpp:59:28: 错误:使用未声明的标识符 'sortFunc' mergePointer = sortFunc(); ^

我最初认为问题是范围分辨率,所以我在前面添加Merger::sortFunc(),我得到了同样的错误。我不熟悉多态性,甚至不确定我想要做的事情是否可行,有什么想法吗?

class Algorithm{

private:
public:

    vector<int> data;

    static std::vector<void (*)(std::vector<int>&)> algo;

    void (*activeAlgo)(std::vector<int>&);

    enum SortingAlgorithms{
        Merge = 0, Insertion, Bubble, Last
    };

    void load(){
        void (*mergePointer)(vector<int>&);
        mergePointer = sortFunc();
        algo.push_back(mergePointer);
    }
    
    void select(SortingAlgorithms sort){
        
    }
    
};

//abstracted class
class Sort: public Algorithm{
private:
public:
    virtual void sortFunc() = 0; //pure virtual function  
};

class Merger: public Sort{
private:
public:
    void sortFunc(){
        data = mergeSort(data);
        print(data);
    }
};

class Insertion: public Sort{
private:
public:
    void sortFunc(){
        printVec(data);
        insertionSort(data);
        printVec(data);
    }
};

class Bubble: public Sort{
private:
public:
    void sortFunc(){
        printVector(data);
        bubbleSort(data);
        printVector(data);
    }
};

int main(){
    Sort *myAlgo;
    myAlgo->select(Algorithm::Bubble);
}

标签: c++

解决方案


请注意,它void(*)(std::vector<int>&)只能指向命名空间函数或静态成员。指向成员的指针是特定于类的,必须使用特殊运算符.*or调用->*。您可以实现的是具有虚拟基类的 CRTP(为简洁起见,去掉了静态向量和其他花里胡哨):

#include <iostream>
#include <cstdlib>

    class ActorBase
    {
    public:
       // virtual interfaces
       virtual void action() = 0;
    };

    template <class  T>
    class Actor : public ActorBase
    {
    protected:
        typedef void(T::* FuncPtr)(/* params */);
        FuncPtr algo;
    public:
        void action() 
        { 
            /* do call algo for appropriate object by treating this as pointer to T */
            (dynamic_cast<T*>(this)->*algo)(/* args */);
        }
    };

    class Concrete : public Actor<Concrete>
    {
       void bar() {  std::cout << "Hello, Concrete!" << std::endl; }
    public:
       Concrete() { algo = &Concrete::bar; }
    };

int main()
{
    Concrete a;
    a.action();
    return EXIT_SUCCESS;
}

Curiously Recurrent TemplateActor是一个非常特殊的模板,它可以将指向自身的指针转换为派生类。尽管如此,它仍然不知道任何关于的信息Concrete,例如 typedef 或成员。如果它需要传递一些这样的特征,Actor 应该从一个专门用于具体T的模板类派生出来,称为特征类。

虽然不确定这种变态的方法是解决您的 X 问题实际需要的方法,但至少它在语法上是正确的。是一个规范的 CRTP。

请注意,成员指针的调用需要.*\ ->AND 括号,因为调用运算符()的优先级高于.*.


推荐阅读