0

I am using some objects of different classes inheriting from a base class in a method. Now I have the problem that when the object has a specific class in its inheritance structure I don't want the method to be executed.

A (pseudo)code example would look like this:

class A {};
class B : A {};
class C : A {};
class D : B {};
class E : C {};

void method(A* _object)
{
    // If _object is of type C
    // return;
    // else do sth
}

I already checked this question but it doesn't help me because the name that is returned depends on the compiler if I understood one of the answers correctly.

EDIT: Because there were answers that I should rethink my program structure I realized that it is important to mention that I have no insight and no real chance to change the structure of the base classes because I am using a third-party library and the method I mentioned here is an virtual method from one of these base classes. So the accepted answer is good if you face a similiar problem but if you have a program that does not depend on third-party libraries it is better to rethink the structure and do sth like Petar Velev described in his answer.

Rafiwui
  • 544
  • 6
  • 19
  • If you take your object by value, you have slicing and only `A` even if you pass a `C`. – Jarod42 Oct 09 '17 at 09:57
  • `A _object` is always of a type `A`. Maybe you wanted a reference or a pointer? If so, `dynamic_cast` is the answer – Fureeish Oct 09 '17 at 09:58
  • If `A` is polymorphic, virtual method / `dynamic _cast` can be used. – Jarod42 Oct 09 '17 at 09:58
  • 3
    _"Now I have the problem ..."_ That's usually a clear indicator for a flawed design. You should think that over. – user0042 Oct 09 '17 at 09:59
  • if `A` is not polymorphic, then you may use overloads (but only rely on static type) – Jarod42 Oct 09 '17 at 09:59
  • @Fureeish oh yes you are right I have an `A*`. Updating the question... – Rafiwui Oct 09 '17 at 09:59
  • In this case, take a look at [`dynamic_cast<>`](http://en.cppreference.com/w/cpp/language/dynamic_cast), however keep in mind that you usually want to avoid using it. If you cannot change the design, this is the way, however if you are able to redo it, I would highly encourage you to do so – Fureeish Oct 09 '17 at 10:05
  • 3
    Make `do_sth()` a virtual function in `A`. In class `C` add a version that doesn't do anything. – Bo Persson Oct 09 '17 at 10:10

3 Answers3

3

If you introduce a function foo say,

struct A {virtual void foo(){}};
struct B : A {};
struct C : A {void foo() final {/*a no-op*/}};
struct D : B {};
struct E : C {};

Then void method(A* _object) can call foo using _object->foo();. Specifically the override in C is a no-op. Marking that override final means that the method cannot be reintroduced in child classes of C; for example E.

Being able to introduce finality into virtual functions has been part of the C++ standard from C++11 onwards.

This is stylistically preferable to using dynamic_cast.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

You can use the object-oriented way. Make this method a virtual method in your base class A.

Then add the do smth in class A and override it to do nothing in class C.

Petar Velev
  • 2,305
  • 12
  • 24
0
void method(A* _object)
{
    C* c_object = dynamic_cast<C*>(_object);
    if (c_object)
       return;
    // else do sth
}

As Massimiliano Janes and Fureeish say in the comments, you need A to be polymorphic. It can be done by defining a virtual method:

class A {
   virtual ~A() = default;
};
Oneiros
  • 4,328
  • 6
  • 40
  • 69
  • can you distinguish between an `E` and a `C` ? – 463035818_is_not_an_ai Oct 09 '17 at 10:05
  • this is wrong, dynamic_cast needs a polymorphic type, A is not – Massimiliano Janes Oct 09 '17 at 10:06
  • @tobi303 Is that a requirement? I don't see it in OP's question – Oneiros Oct 09 '17 at 10:07
  • OP wants to do something if the object is of type `C` and something else otherwise. That implicitly requires to distinguish a `C` from an `E` (if i didnt misunderstand the question ;) – 463035818_is_not_an_ai Oct 09 '17 at 10:08
  • 1
    @tobi303 there is no need to distinguish between them. if it is C or E or anything else inheriting from C there should always be a return – Rafiwui Oct 09 '17 at 10:09
  • 1
    @Rafiwui, just wanted to mention that this requires public inheritance if you plan to use it like in your example. Additionally, you would need `A` to be polymorphic. Simple `virtual ~A() = default` will do the trick – Fureeish Oct 09 '17 at 10:13
  • This worked for me so I'm gonna accept it as an answer even if it is a bit dirty comparing to the answer of Petar. But it is fitting my needs because I have no insight into the base classes (external library) so thx :) – Rafiwui Oct 09 '17 at 10:25