Superclass Link

I would like to use the visitor pattern in conjunction with smart pointers, but it seems that the compiler cannot detect the subclass and match the corresponding function.

I wrote an SSCE showing the problem:

test.hpp:

class Visitor;
class Area {
public:
    virtual void visit(const Visitor& visitor) = 0;
};

class Area1 : public Area {
public:
    virtual void visit(const Visitor& visitor);
};

class Area2 : public Area {
public:
    virtual void visit(const Visitor& visitor);
};

class Visitor {
public:
  virtual void visit(const Area1 &area) const = 0;
  virtual void visit(const Area2 &area) const = 0;
};

test.cpp:

#include "test.hpp"

void Area1::visit(const Visitor& visitor) {
    visitor.visit(*this);
}

void Area2::visit(const Visitor& visitor) {
    visitor.visit(*this);
}

main.cpp

#include <iostream>
#include "boost/shared_ptr.hpp"
#include "test.hpp"

class FooVisitor : public Visitor {
    virtual void visit(const Area1 &area) const {
        std::cout <<"visit area1" <<std::endl;
    };
    virtual void visit(const Area2 &area) const {
        std::cout <<"visit area2" <<std::endl;
    }
};

int main(int argc, char** argv) {
    boost::shared_ptr<Area> p(new Area2);
    FooVisitor visitor;
    visitor.visit(*p);
    return 0;
}

The line visitor.visit (* p) gives the following error:

main.cpp: In functionint main(int, char**)’:
main.cpp:17:21: error: no matching function for call toFooVisitor::visit(Area&)’
main.cpp:17:21: note: candidates are:
main.cpp:6:18: note: virtual void FooVisitor::visit(const Area1&) const
main.cpp:6:18: note:   no known conversion for argument 1 fromAreatoconst Area1&’
main.cpp:9:18: note: virtual void FooVisitor::visit(const Area2&) const
main.cpp:9:18: note:   no known conversion for argument 1 fromAreatoconst Area2&’

How can I help the compiler understand that a visit (const Area2 &) should be called without resorting to dynamic_cast attempts for each of the subtypes?

+4
source share
2 answers

, *p Area& ( ). . , visit(), Area, :

int main(int argc, char** argv) {
    boost::shared_ptr<Area> p(new Area2);
    FooVisitor visitor;
    p->visit(visitor);
    return 0;
}

, Area::visit() .

+7

(...):

void visit (const Area1 & area) void visit (const Area2 & area)

-, / Area1 Area2. Area, dynamic_cast .

, . -

Area *p = new Area2();
FooVisitor v;
p->visit(v);

.

0

Source: https://habr.com/ru/post/1530003/


All Articles