简体   繁体   English

无法在C ++的派生类中重载基类方法

[英]Cannot overload base class method in derived class in C++

What I am trying to do 我要做什么

I am converting an existing code base which uses dynamic_casting to identify the derived class (shape) to apply derived class specific processing, to a scheme which is based on the visitor pattern. 我正在将使用dynamic_casting标识派生类(形状)以应用派生类特定处理的现有代码库转换为基于访问者模式的方案。 To this effect, I have added a processMe method to the base class (virtual) and in each derived class and a handleShape method to a ShapeProcessor class, one for each type of shape to be processed, typical of the visitor pattern. 为此,我在基类(虚拟)中添加了一个processMe方法,并在每个派生类中添加了一个ShapeShape类的handleShape方法,每种要处理的形状类型(典型的访客模式)都添加了一个handleShape方法。 I have a ShapeProcessor abstract base class that has one pure virtual method that forces the user to provide a catch all shape processor and allows the user to derive from the ShapeProcessor and add other shape processing methods as desired (eg MyShapeProcessor : public ShapeProcessor) 我有一个ShapeProcessor抽象基类,该类具有一个纯虚拟方法,该方法强制用户提供所有形状的处理器,并允许用户从ShapeProcessor派生并根据需要添加其他形状处理方法(例如MyShapeProcessor:public ShapeProcessor)

Observation 观察

However what find is that only the catch all method gets called in MyShapeProcessor for all shapes, my shape specific methods are not getting called. 但是,发现的是,对于所有形状,仅在MyShapeProcessor中调用了catch all方法,而没有调用形状特定的方法。 What do I need to do to get the shape specific methods to get called as desired? 我需要做些什么才能获得所需的形状特定方法? Caveat: If I put all handler methods in one class, it works fine. 警告:如果我将所有处理程序方法放在一个类中,它将很好地工作。 Does this mean that it is not possible to overload methods in the base class? 这是否意味着不可能在基类中重载方法? I have read the posts on name hiding, but that does not seem to apply here. 我已经阅读了有关隐藏姓名的帖子,但似乎不适用于此处。 Or does it? 还是呢? I tried to unhide the base class method using "using" but does not seem to help. 我试图使用“使用”取消隐藏基类方法,但似乎无济于事。

Here is the pseudo code example: 这是伪代码示例:

class Shape {
    virtual void processMe (ShapeProcessor * sp) {
        sp->processShape (*this);
}

// User derived shape
class Circle : public Shape {
    void processMe (ShapeProcessor * sp) {
        sp->processShape (*this);
}

// Base ShapeProcessor
class ShapeProcessor {
    virtual void processShape (Shape& shape) = 0; // User must provide a catch all method
}

// User provided shape processor
class MyShapeProcessor : public ShapeProcessor {
    void processShape (Circle& circle) {
       // Never gets called, even for Circle objects!
    }
    void processShape (Shape& shape) {
       // Always gets called for all shapes!
       cout << "Unsupported shape!" << endl;
    }
}

// User code
Circle * circle = new Circle();
MyShapeProcessor * sp = new MyShapeProcessor();
circle->processMe (sp);  

// Expecting processMe to eventually call MyShapeProcessor processShape (Circle) but calls processShape (Shape)

// Caveat: If I get rid of the ShapeProcessor base class and if I put all shape handles in a single class
// it works fine. Does this mean that it is not possible to overload methods in the base class? I have read
// the posts on name hiding, but that does not seem to apply here. Or does it?

You need to add: 您需要添加:

void processShape (Circle& circle);

to ShapeProcessor as a virtual member function. ShapeProcessor作为virtual成员函数。 Without that, this function is not visible from any of the processMe functions. 否则,该功能将无法从任何processMe函数中看到。

class ShapeProcessor {
    virtual void processShape (Shape& shape) = 0;

    virtual void processShape (Circle& circle) = 0;

};

When you add a new sub-type of Shape in your project, you have to come back to ShapeProcessor and add a new processShape function for the sub-type. 在项目中添加Shape的新子类型时,必须返回ShapeProcessor并为该子类型添加新的processShape函数。

You can use templates to avoid some of this tight coupling. 您可以使用模板来避免这种紧密耦合。 Take a look at https://stackoverflow.com/a/7877397/434551 . 看看https://stackoverflow.com/a/7877397/434551

Would this approach also suit you?? 这种方法也适合您吗?

#include <iostream>


class Shape;


class ShapeProcessor {
public:
    virtual void processShape(Shape &shape){
        std::cout<<"Shape Processor";
    }
};

class CircleProcessor: public ShapeProcessor {

public:
    void processShape(Shape &shape)
    {
        std::cout<<"CircleProcessor";
    }
};
class  Shape
{
public:

    virtual void processMe(ShapeProcessor *sp){
        sp->processShape(*this);
    }
};
class Circle:public Shape
{
public:
    void processMe(ShapeProcessor *sp){
        sp->processShape(*this);
    }
};

int main(int argc, const char * argv[])
{
    Shape  *circle = new Circle();
    ShapeProcessor *sp = new CircleProcessor();
    circle->processMe(sp);
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM