Determine an object's class returned by a factory method (Error: function does not take 1 arguments

StackOverflow https://stackoverflow.com/questions/19446356

Pergunta

I have a factorymethod that either returns an object of baseclass or one that is of derivedclass (a derived class of baseclass). The derived class has a method virtual void foo(int x) that takes one argument. baseclass however has virtual void foo() without an argument.

In my code, a factory method returns a pointer of type bar that definetly points to an object of class derivedclass. However since this is only known at runtime I get a compiler error saying that foo() does not take an argument. Can I cast this pointer to a pointer of type derivedclass?

std::auto_ptr<baseclass> bar  = classfactory::CreateBar(); //returns object of class derivedclass
bar->foo(5);

class baseclass
{
 public:
      virtual void foo();
}

class derivedclass : public baseclass
{
 public:
      virtual void foo(int x);
}
Foi útil?

Solução

To answer your question: you can use static_cast if you know for certain that the instance is of the proper type, or dynamic_cast otherwise. Something like this:

std::auto_ptr<baseclass> bar = classfactory::CreateBar();

if (derivedclass *der = dynamic_cast<derivedclass*>(bar.get())) {
  der->foo(5);
}

However, code like this generally hints at bad design. You shouldn't need to access specifics of the derived class. Perhaps the base class interface is not as complete as it should be?

Outras dicas

You can cast a baseclass* to a derivedclass*.

Using static_cast: if the runtime type of the baseclass* is not (a subclass of) derivedclass*, you get undefined behavior.

Using dynamic_cast: if the runtime type of the baseclass* is not (a subclass of) derivedclass*, the cast yields a null pointer. To allow this behaviour, additional runtime checks are performed.

Right now your bar variable is of baseclass type, so you cannot execute foo(int x). You need convert it to appropriate type, something like this:

std::auto_ptr<baseclass> bar  = classfactory::CreateBar(); //returns object of class derivedclass
std::auto_ptr<derivedclass> bar_derived(dynamic_cast<derivedclass*>(bar.get()) ? (static_cast<derivedclass*>(bar.release())) : 0 );
bar_derived->foo(5);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top