Overloading a pure virtual function with a different set of arguments

Consider the following code example

#include <iostream>
using namespace std;

class Color
{
public:
    virtual void mixColors(Color &anotherColor) = 0;
};

class RGB : public Color
{
public:
    void mixColors(RGB &anotherColor);
};

void RGB::mixColors(RGB &kol)
{
    return RGB(0xABCDEF);
}

I understand why this code does not work ( mixColors () in RGB does not implement a pure virtual function, because it has a different set of arguments). However, I would like to ask if there is another approach to solving this problem. Say I would like to mix colors, but using different algorithms for different classes of colors. I would appreciate any help.

+4
source share
5 answers

Why do you still need a virtual method?

RGB , RGB, mixColor(Color).

, :

class RGB : public Color
{
public:
    void mixColors(RGB &anotherColor);
    void mixColors(Color &c) override { return mixColors(dynamic_cast<RGB&>(c)); }
};

void RGB::mixColors(RGB &kol)
{
    return RGB(0xABCDEF);
}

, , RGB .

+4

, , ++, - " " . ( , .) . .

, , Color - :

virtual void mixColors(Color &anotherColor) = 0;

, ( ) . .

:

// 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) { ... }

, , :

class RGB
{
    // ...
public:
    RGB & mix_colors(RGB);  // return *this at the end
};

class CMYK
{
    // ...
public:
    CMYK & mix_colors(CMYK);  // return *this at the end
};

-: , . , , , , ++ Haskell Common Lisp multi . , , .

+3

RGB . RGB.

RGB , . , . if(dynamic_cast<RGB*>(&anotherColor)) { ... } else { ... }.

+1

. , ( ), , .

:

#include<iostream>

class Color {};

class CMYK;

class RGB : public Color 

{ 
    public: 
        RGB() = default; 
        RGB(const RGB&) = default;

        RGB(const CMYK& c)
        {

        }
};


class CMYK : public Color 
{ 
    public:

        CMYK() = default; 
        CMYK(const CMYK&) = default;

        CMYK(const RGB& r)
        {
        }
};


class colorMixer
{
    public: 

        RGB mixColors(RGB r1, RGB r2)
        {
            std::cout << "mixing RGB , RGB" << std::endl;
            return RGB(); 
        }

        CMYK mixColors(CMYK c1, CMYK c2)
        {
            std::cout << "mixing CMYK, CMYK" << std::endl;
            return CMYK();
        }

        CMYK mixColors(CMYK c1, RGB r1)
        {
            // Convert RGB to CMYK
            CMYK c2(r1);

            return mixColors(c1, c2);
        }

        RGB mixColors(RGB r1, CMYK c1)
        {
            // Convert CMYK to rgb. 
            RGB r2(c1);  
            return mixColors(r1, r2);

        }
};

int main(int argc, const char *argv[])
{
    CMYK c1,c2; 
    RGB r1,r2; 

    colorMixer m1;

    m1.mixColors(c1,c2); 
    m1.mixColors(c1,r1); 
    m1.mixColors(r1,c1); 
    m1.mixColors(r1,r2); 

    return 0;
}
+1

. - , , . , , .

, . , . , :

class Color
{
public:
    virtual ~Color(void) = 0;
    virtual auto mix_colors(Color& color) -> Color&
    {
        throw std::logic_error("Cannot mix unrelated color schemes");
    }
};
Color::~Color(void)
{ /* */ }

, std::cerr - . .

:

class HSL; class HSV; class RGB;
class RGB: public Color
{ /* */ };
class HSV: public Color
{
public:
    auto mix_colors(HSL& color) -> HSV&
    {
        std::cout << "Mixing HSV with HSL" << '\n';
        return *new HSV{};
    }
};
class HSL: public Color
{
public:
    auto mix_colors(HSV& color) -> HSL&
    {
        std::cout << "Mixing HSL with HSV" << '\n';
        return *new HSL{};
    }
};

Here I have three color schemes RGB, HSV and HSL. Of course, they can be mixed with each other, but right now I just implemented the conversion function from HSL to HSV and vice versa.

Now I can do this:

int main(void)
{
    RGB rgb{};
    HSV hsv{};
    HSL hsl{};

    HSV new_hsv{hsv.mix_colors(hsl)};  // Mixing HSV with HSL
    HSL new_hsl{hsl.mix_colors(hsv)};  // Mixing HSL with HSV
    RGB new_rgb{rgb.mix_colors(hsv)};  // terminating with uncaught exception of type std::logic_error: Cannot mix unrelated color schemes Abort trap: 6
}
+1
source

Source: https://habr.com/ru/post/1542653/


All Articles