3

I'm stuck and already tried a alot to solve this "virtual" problem and so I beg you to help me, cause it's probably something stupid that a "trained eye" can solve in seconds..

The problem: When I do the following in main:

PrologConnector swiProlog;
swiProlog = PrologConnector::connectorFactory(PrologConnector::swi,argv);
swiProlog.send("blabla");

always the send method of the PrologConnector class is called, but not the one from the subclass.. Do you see the problem?

Thanks for the help!!

Here's the code: PrologConnector.h

class PrologConnector {
   virtual int send(char * cmd);
   virtual int init(char **argv);
   static PrologConnector connectorFactory(Prolog prolog, char ** argv);
};

PrologConnector.cpp

int PrologConnector::send(char * argv) {
  std::cout << "not wanted"<<std::endl;
  return 0;
}


int PrologConnector::init(char **argv) {
  //TODO add implementation
  return 0;
}


PrologConnector PrologConnector::connectorFactory(Prolog prolog, char **argv) {
  if (prolog == swi) {
    SWIConnector sc;
    sc.init(argv);
    return sc;
  }

std::cout <<"Error in initialization!"<<std::endl;
PrologConnector pc;
return pc;
}

SWIConnector.h:

class SWIConnector : public PrologConnector {
  int send(char *cmd);
  int init(char **argv);
};

SWIConnector.cpp:

int SWIConnector::init(char **argv) {
//some action going on
}


int SWIConnector::send(char * cmd) {

//some action going on
}
Frempe
  • 269
  • 4
  • 11
  • 1
    You can only call overridden functions via the base class if you create a pointer to the base class' object and initialize it with an instance of a derived class. – Daniel Kamil Kozar Dec 05 '12 at 23:02
  • [What is the slicing problem in c++](http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c) – jrok Dec 05 '12 at 23:03

4 Answers4

6

What you have here is object slicing. In order to use objects polymorphically, you have to access them through a pointer or a reference.

The signature of your factory method should be changed to return a PrologConnector* or PrologConnector&, after which you will be able to see the expected behavior.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • Yes-- connector factory should return a reference to the created object, which should be allocated on the heap. – antlersoft Dec 05 '12 at 23:06
  • @PreetSangha: I 'm not sure what you are asking. – Jon Dec 05 '12 at 23:06
  • 1
    The *usually* and *more rarely* in the answer are purely speculative. While polymorphic storage of objects is done through pointers, **access** is often done through references. – David Rodríguez - dribeas Dec 05 '12 at 23:16
  • @jon - no problem. I wanted to understand where the copy of was happening as opposed to the assignment (as the OP expected). With references or pointers it's easy to comprehend. – Preet Sangha Dec 05 '12 at 23:54
4

The problem is common and is called "slicing". You're assigning a derived class to an instance of the base class, and all attributes of the derived class are being lost during the copy.

Use a pointer or reference to the class instead.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
2

Here is what happens in this method:

PrologConnector PrologConnector::connectorFactory(Prolog prolog, char **argv) {
  if (prolog == swi) {
    SWIConnector sc;
    sc.init(argv);
    // return sc;
    return PrologConnector(sc);
  }

as you return variable of the type PrologConnector. And PrologConnector's methods will be called.

You need to return pointers rather than copy of objects.

c-smile
  • 26,734
  • 7
  • 59
  • 86
0

Thanks for the answers, that was exactly what happened.. Never heard about that before :)

Another hint:

PrologConnector* PrologConnector::connectorFactory(Prolog prolog, char **argv) {
  if (prolog == swi) {
  SWIConnector *sc = new SWIConnector;
  sc->init(argv);
  return sc;
} 

I had to use "new" to instantiate that SWIConnector, otherwise I get a "segmentation fault" in the main function. I am not completely sure why, because I thought the "SWIConnector x" already allocates memory, but there seems to be another reason :)

Regards

Frempe
  • 269
  • 4
  • 11