In a language where inheritance entails subtyping, such as C++, you cannot make a member function argument "more specific" in a derived class. (At least not without breaking type safety.) For a full technical explanation, see here.
To understand this in more concrete terms, notice that, in your Color
class, you are asserting the existence of a member function with signature:
virtual void mixColors(Color &anotherColor) = 0;
This means that any color can be mixed with any other color (not necessarily of the same class), and that the concrete implementation of this mixing procedure only depends on the class of the first color. Which is just plain wrong.
The simplest solution to your probem is to simply use function overloading:
// I am assuming RGB and CMYK are cheap to pass by value, which seems reasonable.
// If this is not true, you can always pass them by const reference.
RGB mix_colors(RGB rgb1, RGB rgb2) { ... }
CMYK mix_colors(CMYK cmyk1, CMYK cmyk2) { ... }
Or, assuming you really want to mutate one of the colors, instead of producing a new color object:
class RGB
{
// ...
public:
RGB & mix_colors(RGB); // return *this at the end
};
class CMYK
{
// ...
public:
CMYK & mix_colors(CMYK); // return *this at the end
};
There is a downside to using overloading instead of virtual member functions, however: overloads must be resolved at compile time, while virtual member functions can be dynamically dispatched. Sadly, if you need to perform runtime dispatch on the colors you want to mix, you are kind of screwed, because C++ has nothing like Haskell's type classes or Common Lisp's multimethods. You can encode multiple dispatch using the visitor pattern, but this is decidedly not pretty.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…