C++虚方法问题

发布于 2024-11-05 18:06:37 字数 1402 浏览 5 评论 0原文

我有两个结构,我试图在其中覆盖基本结构中的方法。

基本结构定义为:

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

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

I have two structs, in which I'm trying to overwrite a method in the base struct.

The base struct is defined as:

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

The struct I'm attempting to subclass with is defined as:

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

I don't see what I'm doing wrong here, any help would be greatly appreciated.
Ideally, the method in valuecomparer would be called instead of the method in compareFunction.

It is being called basically like this (not necessarily valid syntax,but trying to get idea across):

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

Apparently after switching the storage from a pure struct to a struct pointer in the class that is using the base struct (and consequently derived struct), everything works. Thanks for all the help :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

潜移默化 2024-11-12 18:06:37

根据您发布的代码,为了调用重写的派生类的函数,您必须从基类类型的指针或引用调用它,而不是从其类型的对象调用它是基类本身的。因此,当您创建这样的代码时:

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

现在,当在 x 上调用 operator() 方法时,将使用正确的 v-table 条目,即覆盖的版本valuecomparer 内部的 operator()

According to the code you've posted, in order to have a overridden derived class' function to be called, you MUST call it from a pointer or reference to the base class type, not an object whose type is of the base class itself. So when you create code like this:

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

that's always going to call the function definition in the base-class since there is no function that can be used for the polymorphic derived function call. The copy-constructor only copies over the v-table entries and associated members from the base-class. So when you call a method on an object of the base-class type, even if you've created that object from a copy of a derived class, you still end up with the base-class method calls. You would have to-do something like this:

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

Now when the operator() method is called on x, the correct v-table entry is used, that is the overridden version of operator() inside of valuecomparer.

无言温柔 2024-11-12 18:06:37

问题是,从您的伪代码中,您正在切片比较器:

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< 的引用/code>,而不是一个成熟的实例。

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

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

The problem is, from your pseduo-code, you're slicing your comparer:

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

The easiest solution, given the context, would be the change the declaration of x to be a reference to cmpType, instead of a full-blown instance.

Edit:
Looking closer, the above will not work, at all (you said it was psuedo), but given the intent, looks like you've meant:

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));
心在旅行 2024-11-12 18:06:37

如果您将 valuecomparer 用于 std::map,那么您就忽略了映射中的项目被定义为 std:: 的事实。对。看到 const 部分了吗? :) 将其添加到您的 std::pair 中。如果这不是问题,请报告您实际使用这些函子的位置和方式。

If you're using your valuecomparer for a std::map, then you're missing the fact that an item in the map is defined as std::pair<const Key, Val>. See the const part? :) Add that to your std::pair<>s. If that isn't the problem, report back where and how you actually use those functors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文