How to distinguish from parent to chlid class interface

Let's say that I have a parent class Parentand child classes Child1and Child2, in which the latter implements MyInterface:

class Parent {
    public:
        Parent();
        virtual ~Parent();
        virtual void MyMethod();
}
class MyInterface {
    public:
        virtual ~MyInterface() {}
        virtual void MyInterfaceMethod() = 0;
}
class Child1 : public Parent {
    public:
        Child1();
        virtual ~Child1();
}
class Child2 : public Parent, MyInterface {
    public:
        Child2();
        virtual ~Child2();
        virtual void MyInterfaceMethod() override;
}

And I will say that I am assigned a pointer Parent*, and I want to check if the object implements MyInterface, and if so, add it to MyInterface*.

I tried to achieve this like this:

void MyFunction(Parent* p) {
    MyInterface* i = dynamic_cast<MyInterface*>(p);
    if (i != 0)
        DoSomething();
    else
        cout << "Cannot do anything.";
}

But I am always 0, which says that it is never subject to type MyInterface*, even if I know for sure that the object is of good type.

How do I achieve this?

+4
source share
3 answers

Child2 private MyInterface, MyFunction() private, dynamic_cast .

MyInterface , , public.

class Child2 : public Parent, public MyInterface { }
//                            ~~~~~~      

LIVE ( )

+2

dynamic_cast .

-

virtual ~Parent() = default;

public Parent. dynamic_cast , .

+1

Alternatively, dynamic_castwe can use the visitor template instead :

#include <iostream>

class MyInterface {
public:
    virtual void DoSomething() = 0;
};

class Parent {
public:
    virtual ~Parent() = default;
    virtual void accept(class Visitor& visitor) = 0;
};

class Child1 : public Parent {
public:
    virtual void accept(Visitor& visitor);
};

class Child2 : public Parent, public MyInterface {
public:
    virtual void accept(Visitor& visitor);
    virtual void DoSomething();
};

class Visitor
{
public:
    void visit(Child1& child);
    void visit(Child2& child);
};

void Child1::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::DoSomething() { std::cout << "Do something.\n"; }

void Visitor::visit(Child1& child) { std::cout << "Cannot do anything.\n"; }
void Visitor::visit(Child2& child) { child.DoSomething(); }

void MyFunction(Parent& p) {
    Visitor v;
    p.accept(v);
}

int main()
{
    Child1 c1;
    Child2 c2;
    MyFunction(c1);
    MyFunction(c2);
}

Conclusion:

Cannot do anything.

Do something.

0
source

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


All Articles