convert constructor to function pointer

Motivation: provide a specialized container, that could only be used with the derived types of some class.
So a colony contains microorganisms of the same specie. But I want to avoid the creation of a different colony type for every microorganism (i.e. a template).

I though of a function pointer (initialised in the constructor) that will be responsible of create the instances. However I don't like how I am doing that. Is there a simpler method?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//class Microorganism;
//class Bacilo: public Microorganism;
//class Coco: public Microorganism;

typedef Microorganism * (*create_function)();

class Colony{
private:
    std::vector<Microorganism *> colony;
    create_function create;
public:
    Colony( create_function c ): create(c){}
    void add(){
        colony.push_back( create() );
    }
//...
};
template<class T> Microorganism* constructor(){ return new T(); }
template<class T> create_function create_constructor(){
    return &constructor<T>;
}

int main(int argc, char **argv){
    Colony player( create_constructor<Bacilo>() );
//...
    return 0;
}
Last edited on
Virtual functions instead of function pointers?

My class names aren't perfect here, but you get the idea:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ColonyBase
{
private:
  std::vector<Microorganism*> colony;

public:
  virtual void add() = 0;
};

template <typename T>
class Colony : public ColonyBase
{
public:
  void add()
  {
    colony.push_back(new T());
  }
};

//...
int main()
{
  Colony<Bacilo> player;

  player.add(); // etc.
}
1
2
template <typename T> //this is what I want to avoid
class Colony : public ColonyBase
Some context: http://alifecontest.wikidot.com/ It's a "game" where every player provides an implementation for a Microorganism (MOs), and they fight to the death.
The code uses templates for defining the colonies, so I though that providing a template specialization for the MO, you could break the rules.
However it seems that the environment provides the colonies a copy of the data, so it will just fool itself.

Another issue (this could be avoided with your design):
1
2
3
4
5
6
template < class MO = Microorganism > class CppColony;

vector< CppColony<Microorganism > *> colonies;
CppColony<Microorganism> *mo = NULL;
mo = (CppColony < Microorganism > *) new CppColony< Bacilo >(); //how dangerous is this?
colonies.push_back(mo);
this is what I want to avoid [snip] The code uses templates for defining the colonies, so I though that providing a template specialization for the MO, you could break the rules.


I'm not sure I follow. The only template you could specialize here would be Colony -- and the only thing that would do is let you change the add() function, which wouldn't allow them to "cheat" at all.

All the rest of the code would be using ColonyBase, as far as I can tell.

If you want to go even further than that you could do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ColonyBase
{
private:
  std::vector<Microorganism*> colony;

public:
  void add()
  {
    colony.push_back( generate() );
  }

  virtual Microorganism* generate() const = 0;
};

template <typename T>
class Colony : public ColonyBase
{
public:
  virtual Microorganism* generate() const
  {
    return new T();
  }
};


Now it means even less to specialize Colony because generate() can't even modify 'this', since generate is const.

mo = (CppColony < Microorganism > *) new CppColony< Bacilo >(); //how dangerous is this?


Extremely dangerous. It's a bad cast. It could very well blow up in your face.
The only template you could specialize here would be Colony -- and the only thing that would do is let you change the add() function, which wouldn't allow them to "cheat" at all.
But you could access every public method of the base class from Colony::add.
Making it const was great. Thanks.
Topic archived. No new replies allowed.