首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++虚函数覆盖

C++虚函数覆盖
EN

Stack Overflow用户
提问于 2015-04-11 18:15:50
回答 2查看 75关注 0票数 1

我有一个类,它包含以下虚拟方法:

代码语言:javascript
复制
struct point {
    template<typename T>
    virtual typename std::enable_if<std::is_base_of<point, T>::value, double>::type distTo(T &other) const = 0;
};

上面的内容不起作用,因为:

代码语言:javascript
复制
error: templates may not be ‘virtual’

其计划是通过创建更具体的类实例(如point2Dpoint3D )来专门化该类。但是,我只想让函数处理同一个类的类型。因此,如果point2D在何处继承该类,则方法distTo只应接受point2D类型的参数。我怎样才能做到这一点?

这就是我在做上述工作之前所做的尝试:

代码语言:javascript
复制
virtual double distTo(point& other) = 0;

但是,当我在point2D类中重写此方法并尝试将参数替换为point2D类型之一时,会遇到编译器错误。

耽误您时间,实在对不起

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-11 18:19:53

我认为对于静态类型化语言(如C++ )来说,您的需求是没有意义的。

想一想如何使用虚拟函数:

代码语言:javascript
复制
point2d p1, p2;
point3d p3;

point &p = p1;

p.distTo(p2); //ok?
p.distTo(p3); //error?

这是不可能的,因为在编译时编译器将不知道p是对point2d还是point3d的引用,只在运行时。

如果您做错了,可以添加显式强制转换和运行时断言,但我认为这没有什么意义。只需做:

代码语言:javascript
复制
struct point { /*...*/ };

struct point2d : point {
    double distTo(const point2d &other);
};

struct point3d : point {
    double distTo(const point3d &other);
};

也不要使用基本的distTo引用调用point

UPDATE:如果您知道您的列表是同构的,但不知道基数,那么可以这样做:

代码语言:javascript
复制
struct point {  
    virtual double distTo(const point &other) =0;
};

struct point2d : point {
    double distTo(const point2d &other) { /*...*/ }
    virtual double distTo(const point &other) {
        const point2d &other2 = static_cast<const point2d &>(other);
        return distTo(other2);
    }
};

struct point3d : point {
    double distTo(const point3d &other) { /*...*/ }
    virtual double distTo(const point &other) {
        const point3d &other3 = static_cast<const point3d &>(other);
        return distTo(other3);
    }
};

但要小心!如果您使用错误的对象调用point::distTo,结果将是未定义的!

票数 1
EN

Stack Overflow用户

发布于 2015-04-11 18:21:33

这听起来像奇怪的反复出现的模板模式。此外,这与动态间接性完全不兼容,因为编译器不能静态地验证动态类型(很明显)。但是CRTP只能用于实现函数,而不能声明它。

代码语言:javascript
复制
template<typename T> class Point {
public:
    double distTo(T other) {
        /* stuff */ 
    }
};
class Point2D : public Point<Point2D> {
    // distTo automatically defined
};

从根本上说,您要声明的接口是完全不可能的,因为您要求编译器静态地打印动态类型。没有任何解决方案可以提供您想要的所有属性。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29581389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档