C ++虚方法问题

时间:2011-05-10 03:31:16

标签: c++ inheritance virtual-method

我有两个结构,我正在尝试覆盖基础结构中的方法。

基础结构定义为:

 template <class T>
 struct compareFunction : public std::binary_function<T,T,bool> {
    virtual bool operator() (const T & first, const  T & second) {
        //This function is always called
        return first < second;
    }
 };

我尝试子类化的结构定义为:

template <class Key, class T>
struct valuecomparer : public compareFunction<std::pair<Key,T> > {
    std::binary_function<Key, Key,bool> comparer;

    bool operator() (const std::pair<Key, T>& x, const std::pair<Key, T> & y) {
            //This function is never called
            Key tx = x.first;
            Key ty = y.first;
            if(tx < ty) {
               return true;
            } else {
               return false;
            }
    }
};

我看不出我在这里做错了什么,任何帮助都会非常感激。 理想情况下,将调用valuecomparer中的方法而不是compareFunction中的方法。

它基本上被称为(不一定是有效的语法,但试图了解它):

typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar;
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

显然,在将存储从纯结构切换到使用基本结构(并因此导出结构)的类中的结构指针之后,一切正常。感谢所有的帮助:)

3 个答案:

答案 0 :(得分:2)

根据你发布的代码,为了有一个被覆盖的派生类'函数被调用,你必须从指针或对基类类型的引用中调用它,而不是类型是基类本身的对象。所以当你创建这样的代码时:

cmpType x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

总是会在基类中调用函数定义,因为没有可用于多态派生函数调用的函数。复制构造函数仅复制基表类中的v表条目和关联成员。因此,当您在基类类型的对象上调用方法时,即使您已从派生类的副本创建该对象,您仍然会使用基类方法调用。你必须做这样的事情:

cmpType& x = compareVar;
x(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

现在,当operator()上调用x方法时,会使用正确的v表条目,即operator()valuecomparer的被覆盖版本。< / p>

答案 1 :(得分:1)

问题是,从您的pseduo代码开始,您正在切换比较器:

typedef compareFunction<T> cmpType; //Inside a class definition, T is std::pair<int,double>
valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
cmpType x = compareVar;                     // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

根据上下文,最简单的解决方案是将x的声明更改为cmpType的引用,而不是完整的实例。

修改 仔细观察,上面的内容根本不起作用(你说它是伪装的),但考虑到意图,看起来你的意思是:

valuecomparer<int,double> compareVar;
compareVar.comparer = std:less<int>();
compareFunction<pair<int, double> > x = compareVar;                     // *** SLICED HERE ****
x.compare(std::pair<int,double>(8,20.0),std::pair<int,double>(8,25.0));

答案 2 :(得分:0)

如果您将valuecomparer用于std::map,那么您错过了地图中的项目定义为std::pair<const Key, Val>这一事实。请参阅const部分? :)将其添加到您的std::pair<>。如果这不是问题,请报告您实际使用这些仿函数的位置和方式。