[C++] Polimorfizm, wieloznaczność.
Witam.
Zacząłem ostatnio uczyć się polimorfizmu i natrafiłem na niezłą przeszkodę z tego co wyczytałem jest to tzw. problem diamentu lecz zważywszy na to, że nie jestem pewien tego terminu określę swój problem.
Stworzyłem hierarchię działającą na zasadzie poniższego schematu
Figure
/ \
Rectangle Circle
\ /
Button
chciałbym móc utworzyć Button o kształcie prostokąta ALBO koła i tu pojawia się wieloznaczność.
próbowałem odnieść się do obiektu wyższego poprzez :: ale kompilator odmawia i widzi dwie funkcje dwóch obiektów mimo, że tworzę w konstruktorze Buttona tylko jeden.
dorzucę kod z paru plików.
MAIN.cpp
#include "main.hpp"
using namespace std;
Rect * recta;
Circle * cir;
Button * But;
int main()
{
recta = new Rect( sf::Vector2f( 500, 300 ), sf::Vector2f( 100, 76 ), sf::Color::Blue );
cir = new Circle( sf::Vector2f( 100, 50 ), 20, sf::Color::Red );
But = new Button( false, false, sf::Vector2f( 700, 50 ), 34.f, sf::Color::Green );
while( RWin.isOpen() )
{
RWin.clear();
recta->Draw( & RWin );
cir->Draw( & RWin );
But->Draw( & RWinL );
RWin.display();
}
delete recta;
delete cir;
delete But;
return( 0 );
}
FIGURE.HPP
#ifndef Figure_hpp
#define Figure_hpp
#include <iostream>
#include <SFML/Graphics.hpp>
class Figure
{
public:
sf::Vector2f Pos;
sf::Color Color;
Figure * Next;
Figure();
Figure( sf::Vector2f PosL, sf::Color ColorL );
virtual ~Figure();
void virtual Draw( sf::RenderWindow * RWinL );
};
#endif
FIGURE.CPP
#include "Figure.hpp"
using namespace std;
Figure::Figure()
{
}
Figure::Figure( sf::Vector2f PosL, sf::Color ColorL )
{
cout << "\nstworzylem figure";
}
Figure::~Figure()
{
cout << "\nzniszczylem figure";
}
void Figure::Draw( sf::RenderWindow * RWinL )
{
cout << "\nbrak ksztaltu...";
}
CIRCLE.HPP
#ifndef Circle_hpp
#define Circle_hpp
#include "Figure.hpp"
#include <iostream>
using namespace std;
class Circle
: public virtual Figure
{
public:
float Radius;
Circle * Next;
Circle();
Circle( sf::Vector2f PosL, float RadiusL, sf::Color ColorL );
virtual ~Circle();
void Draw( sf::RenderWindow * RWinL );
};
#endif
CIRCLE.CPP
#include "Circle.hpp"
using namespace std;
Circle::Circle()
{
}
Circle::Circle( sf::Vector2f PosL, float RadiusL, sf::Color ColorL )
: Figure( PosL, ColorL )
{
cout << "\nstworzylem kolo";
}
Circle::~Circle()
{
cout << "\nzniszczylem kolo";
}
void Circle::Draw( sf::RenderWindow * RWinL )
{
cout << "\nnarysowalem kolo";
}
RECTANGLE.HPP
#ifndef Rectangle_hpp
#define Rectangle_hpp
#include "Figure.hpp"
#include <iostream>
using namespace std;
class Rect
: public virtual Figure
{
public:
sf::Vector2f Size;
sf::RectangleShape * Img;
Rect * Next;
Rect();
Rect( sf::Vector2f PosL, sf::Vector2f SizeL, sf::Color ColorL );
virtual ~Rect();
void Draw( sf::RenderWindow * RWinL );
};
#endif
RECTANGLE.CPP
#include "Rectangle.hpp"
using namespace std;
Rect::Rect()
{
}
Rect::Rect( sf::Vector2f PosL, sf::Vector2f SizeL, sf::Color ColorL )
: Figure( PosL, ColorL )
{
cout << "\nstworzylem rect";
}
Rect::~Rect()
{
cout << "\nzniszczylem rect";
}
void Rect::Draw( sf::RenderWindow * RWinL )
{
cout << "\nnarysowalem rect";
}
BUTTON.HPP
#ifndef Button_hpp
#define Button_hpp
#include "Figure.hpp"
#include "Rectangle.hpp"
#include "Circle.hpp"
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
class Button
: public Circle
, public Rect
{
public:
bool Clicked;
bool Pressed;
Button * Next;
Button();
Button( bool IsClick, bool IsPress, sf::Vector2f PosL,
sf::Vector2f SizeL, sf::Color ColorL );
Button( bool IsClick, bool IsPress, sf::Vector2f PosL,
float RadiusL, sf::Color ColorL );
~Button();
void Draw( sf::RenderWindow * RWinL );
};
#endif
BUTTON.CPP
#include "Button.hpp"
using namespace std;
Button::Button( bool IsClick, bool IsPress, sf::Vector2f PosL,
sf::Vector2f SizeL, sf::Color ColorL )
: Rect( PosL, SizeL, ColorL )
{
cout << "\nstworzylem button rect'owy";
}
Button::Button( bool IsClick, bool IsPress, sf::Vector2f PosL,
float RadiusL, sf::Color ColorL )
: Circle( PosL, RadiusL, ColorL )
{
cout << "\nstworzylem button cirl'owy";
}
Button::~Button()
{
cout << "\nzniszczylem button";
}
void Button::Draw( sf::RenderWindow * RWinL )
{
if( Circle != NULL )
Draw( RWinL );
if( Rect != NULL )
Draw( RWinL );
}