Subclass with specific method argument

Hi everyone,

I have an abstract class looking like this:

1
2
3
class MyAbstractClass {
  virtual int getFitness(Gene gene) = NULL;
};


This class is used by another class to .. calculate fitness for its data. Now this data can vary over different classes that may need to calculate fitness, so I <want> their fitness calculating functions to be varied as well. Like this:

1
2
3
4
5
6
class MyFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene_A gene);
};
class MyOtherFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene_B gene);
};

In this case, Gene_A and Gene_B are subclasses of Gene.

Obviously, this won't work, since MyFitnessClass and MyOtherFitnessClass need to implement the getFitness method with [b]Gene[b] as argument.

I can't figure out how to do this neatly. I could give the method a pointer as argument, but that wouldn't be type safe. I would like it to be. Is there a way to have MyAbstractClass have its argument be a type that can be defined per subclass?

I hope that was clear, thanks for the help!

Hmm. I'm not quite sure what you are trying to do. However, if you aren't using pointers and references, you are definitely wasting memory somewhere.

Pointers are type safe.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T>
class method_holder{
public:
   virtual int get_fitness(T);
};

class foo: 
   public if_you_need_a_base_class,
   private method_holder<Gene_B>
{
public:
   using method_holder<Gene_B>::get_fitness; //if you want default behaviour
   virtual int get_fitness(Gene_B); //if you want to override
};
@Vlykarye
The reason I don't want to use pointers, is that I don't want to have to type cast. I want to be sure the pointer is of a specific type.

@ne555
Thanks, that's exactly what I was looking for. It works just like I wanted it to now!
I don't see what's wrong with this:

1
2
3
4
5
6
class MyFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene gene);
};
class MyOtherFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene gene);
};


Since Gene_A and Gene_B are subclasses of Gene, this should work. And the behavior of the getFitness methods can vary between the classes.
virtual int getFitness(Gene gene) = NULL;

That is a bit of an unusual declaration of a pure virtual function.

Normally it looks like this:

virtual int getFitness(Gene gene) = 0;

Even though NULL might evaluate to 0, the problem is that NULL is a C language construct, and can mean 0 or a void pointer. So NULL is not recommended for C++ programs. C++ has nullptr, but that is an entirely different thing to what you want, so just stick to 0 for pure virtual functions. All the documentation I have ever seen uses 0, just wondering why someone would want to change that?
1
2
3
4
5
6
class MyFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene gene);
};
class MyOtherFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene gene);
};




Since Gene_A and Gene_B are subclasses of Gene, this should work. And the behavior of the getFitness methods can vary between the classes.


No, it shouldn't work. The type of the parameters is Gene. It will never be Gene_A or Gene_B. One must use either a pointer or reference to preserve the type of the parameter.
1
2
3
4
5
6
7
8
9
10
class MyAbstractClass {
  virtual int getFitness(Gene gene) = 0;
};

class MyFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene Gene_A);
};
class MyOtherFitnessClass : public MyAbstractClass {
  virtual int getFitness(Gene Gene_B);
};


Is this what you are after?
^ However
1
2
3
4
MyFitnessClass foo;
foo.getFiness( Gene_A() ); //compiles, fine
foo.getFiness( Gene_B() ); //compiles, bad
foo.getFiness( Gene() ); //compiles, bad 


Edit: always calling to the one that receives `Gene_A'
I suppose that http://www.parashift.com/c++-faq/hiding-rule.html is happening.
Last edited on
Topic archived. No new replies allowed.