1

Let's say you have this:

class foo {
public:
  virtual int myFunc() = 0;
  ///...
  virtual bool who()   = 0; // don't want to implement this
};

class bar : public foo {
public:
  int myFunc() {return 3;}
  //...
  bool who() {return true;} // don't want to implement this
};

class clam : public foo {
public:
  int myFunc() {return 4;}
  //...
  bool who() {return false;} // don't want to implement this
};


int main() {

  std::vector<foo*> vec (2, NULL);
  vec[0] = new bar();
  vec[1] = new clam();

  // copy vec and allocate new ptrs as copies of the data pointed to by vec[i]
  std::vector<foo*> vec2 (vec.size(), NULL);
  for ( int i=0; i<vec.size(); ++i ) {

    // obviously not valid expression, but it would be nice if it were this easy
    //vec2[i] = new foo(*vec[i]); 

    // the hard way of copying... is there easier way?
    if (vec[i]->who()) {
      vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
    } else {
      vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
    }

  }

  return 0;
}

What I want is some simple way of having the compiler look up in its bookkeeping and allocating/copying vec2[i] according to the stored type of *vec[i]. The workaround is to just make a virtual function which basically returns a value specifying what type *vec[i] is, then doing a conditional allocation based on that.

user2601195
  • 161
  • 2
  • 9
  • Most times when you find yourself writing `if (object is some type) { do something; } else if (object is some other type) { do something else; }` you should be adding a new virtual function to encapsulate the different behaviors, as in Igor's answer; that's what they are for. – Oktalist Jul 20 '13 at 14:00

3 Answers3

4

A common approach goes like this:

class foo {
public:
  virtual foo* clone() = 0;
};

class bar : public foo {
public:
  virtual bar* clone() { return new bar(*this); }
};

class clam : public foo {
public:
  virtual clam* clone() { return new clam(*this); }
};
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
0

One way you can do it is by using a dynamic cast to determine type of an object such as done here (Finding the type of an object in C++). but the easiest way would probably be to use typeid.

(assuming you want to maintain your way of using type as a determiner, otherwise I would recommend Joachim's or Igor's as better alternatives :) )

Community
  • 1
  • 1
Eiyrioü von Kauyf
  • 4,481
  • 7
  • 32
  • 41
0

you can use the dynamic_cast to downcast and test the type,

bar* pbar = dynamic_cast<bar*>(vec[i])
if (pbar) {
  vec2[i] = new bar ( * static_cast<bar* >(vec[i]) ) ;
} else {
  vec2[i] = new clam( * static_cast<clam*>(vec[i]) );
}

see for more info in dynamic_cast http://www.cplusplus.com/doc/tutorial/typecasting/

Anand Rathi
  • 790
  • 4
  • 11