Есть вот такая программа.
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#include <string.h>
#include <math.h>
void move(int i);
// è½áßß öêâôÉÇ
class Figure
{
protected:
int Color;
int CenterX;
int CenterY;
public:
Figure(int iCenterX, int iCenterY)
{
Color = RED;
CenterX = iCenterX;
CenterY = iCenterY;
}
void SetNewColor(int NewColor)
{
Hide();
Color=NewColor;
Show();
}
virtual void Show() = 0;
virtual void Hide()
{
int prev_col = Color;
Color=getbkcolor();
Show();
Color = prev_col;
}
void Move(int DeltaX, int DeltaY)
{
Hide();
CenterX+=DeltaX;
CenterY+=DeltaY;
Show();
}
virtual ~Figure() {};
};
class Butterfly: public Figure
{
private:
int Radius;
int RadiusX;
int RadiusY;
int Stangle;
int Endangle;
public:
Butterfly(int iCenterX, int iCenterY, int iStangle,int iEndangle,int iRadiusX,int iRadiusY,int iRadius) :
Figure(iCenterX, iCenterY)
{
Stangle=iStangle;
Endangle=iEndangle;
Radius=iRadius;
RadiusX = iRadiusX;
RadiusY = iRadiusY;
}
void Show();
};
class Hexe: public Figure
{
private:
int RRadius;
int rRadius;
public:
Hexe(int iCenterX, int iCenterY, int iRadius) :
Figure(iCenterX, iCenterY)
{
RRadius = iRadius;
rRadius = (sqrt(3)/2)*RRadius;
}
void Show();
};
class Combo:public Hexe,public Butterfly
{
public:
Combo(int iCenterX, int iCenterY, int iStangle,int iEndangle,int iRadiusX,int iRadiusY,int iRadius) :
Hexe( iCenterX, iCenterY, iRadius),Butterfly(iCenterX, iCenterY, iStangle,iEndangle, iRadiusX, iRadiusY,iRadius)
{}
void Show();
void Hide();
void Move(int x);
void SetNewColor(int colr);
~Combo(){};
};
void Hexe::Show()
{
int prev_color=getcolor();
setcolor(Color);
line(CenterX, CenterY+RRadius,CenterX-rRadius,CenterY+RRadius/2);
line(CenterX-rRadius,CenterY+RRadius/2,CenterX-rRadius,CenterY-RRadius/2);
line(CenterX-rRadius,CenterY-RRadius/2,CenterX,CenterY-RRadius);
line(CenterX,CenterY-RRadius,CenterX+rRadius,CenterY-RRadius/2);
line(CenterX+rRadius,CenterY-RRadius/2,CenterX+rRadius,CenterY+RRadius/2);
line(CenterX+rRadius,CenterY+RRadius/2,CenterX, CenterY+RRadius);
setcolor(prev_color);
}
void Butterfly::Show()
{
int prev_color=getcolor();
setcolor(Color);
circle(CenterX, CenterY-RadiusY, Radius/5);
ellipse(CenterX, CenterY+Radius/5, Stangle,Endangle,RadiusX,RadiusY);
line(CenterX-(sqrt(3)/2*Radius),CenterY-Radius/2,CenterX-20,CenterY);
line(CenterX-20,CenterY,CenterX-(sqrt(3)/2*Radius),CenterY+Radius/2);
line(CenterX-(sqrt(3)/2*Radius),CenterY-Radius/2,CenterX-(sqrt(3)/2*Radius),CenterY+Radius/2);
line(CenterX+(sqrt(3)/2*Radius),CenterY-Radius/2,CenterX+20,CenterY);
line(CenterX+20,CenterY,CenterX+(sqrt(3)/2*Radius),CenterY+Radius/2);
line(CenterX+(sqrt(3)/2*Radius),CenterY-Radius/2,CenterX+(sqrt(3)/2*Radius),CenterY+Radius/2);
setcolor(prev_color);
}
void Combo::Show()
{
Butterfly::Show();
Hexe::Show();
}
void Combo::Hide()
{
Butterfly::Hide();
Hexe::Hide();
}
void Combo::Move(int x)
{
Butterfly::Move(15*x,15*x);
Hexe::Move(15*x,15*x);
}
void Combo::SetNewColor(int colr)
{
Butterfly::SetNewColor(colr);
Hexe::SetNewColor(colr);
}
int main()
{ int n_menu;
while (1)
{
clrscr;
cout<<"1-Butterfly\n2-Hexe\n3-Combo\n4-Exit\n";
cin>>n_menu;
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode,
"../BGI");
errorcode = graphresult();
if (errorcode != grOk)
{
cerr<<"Graphics error";
cerr<<grapherrormsg(errorcode);
exit(1);
}
Butterfly F1(100,100,0,360,20,75,100);
Hexe F2(100,100,100);
Combo F3(100,100,0,360,20,75,100);
switch(n_menu)
{
case 1: cleardevice();F1.Show();break;
case 2: cleardevice();F2.Show();break;
case 3: cleardevice();F3.Show();break;
case 4: cout<<"Bay! Bay!\n";delay(750);return 0;
}
getch();
int maxcolor = getmaxcolor();
int direction = 1;
for (int color = 0; !kbhit(); color++)
{
if (color>maxcolor)
{color=0; direction*=-1;}
switch (n_menu)
{
case 1: F1.SetNewColor(color);F1.Move(10*direction,10*direction);break;
case 2: F2.SetNewColor(color);F2.Move(10*direction,10*direction);break;
case 3: F3.SetNewColor(color);F3.Move(direction);break;
}
delay(50);
}
closegraph();
}
}
void Combo::Move(int x)
{
Butterfly::Move(15*x,15*x);
Hexe::Move(15*x,15*x);
}
void Combo::SetNewColor(int colr)
{
Butterfly::SetNewColor(colr);
Hexe::SetNewColor(colr);
}
А теперь еще раз: что выкинуть? Где компилятор матерится? Что ты не хочешь описывать? Приведи тот код, который, как ты думаешь, должен компилироваться, но он не компилируется...
А то на данный момент вообще не понятно, что же тебе в приведенном коде не нравится...
IUnknown, описание класса Combo
class Combo:public Hexe,public Butterfly
{
public:
Combo(int iCenterX, int iCenterY, int iStangle,int iEndangle,int iRadiusX,int iRadiusY,int iRadius) :
Hexe( iCenterX, iCenterY, iRadius),Butterfly(iCenterX, iCenterY, iStangle,iEndangle, iRadiusX, iRadiusY,iRadius)
{}
void Show();
void Hide();
void Move(int x);
void SetNewColor(int colr);
~Combo(){};
};
void Combo::Show()
{
Butterfly::Show();
Hexe::Show();
}
void Combo::Hide()
{
Butterfly::Hide();
Hexe::Hide();
}
void Combo::Move(int x)
{
Butterfly::Move(15*x,15*x);
Hexe::Move(15*x,15*x);
}
void Combo::SetNewColor(int colr)
{
Butterfly::SetNewColor(colr);
Hexe::SetNewColor(colr);
}
#include <iostream>Так что даже не выдумывай, без переопределения в классе Combo этой "прослойки" не обойдешься. Кстати, Липпман именно такой способ называет хорошим тоном программирования.
class A
{
public:
virtual void f()
{
std::cout << "A::f()" << std::endl;
}
};
class B
{
public:
virtual void f()
{
std::cout << "A::f()" << std::endl;
}
};
class C : public A, public B
{
public:
C() : A(), B() { }
};
int main()
{
C obj;
obj.f(); // Какую из функций надо вызывать? Может одну, может обе. Тогда в каком порядке?
return 0;
}
т.е. на всякий случай лучше всегда делать виртуальное наследование?
Кстати, столкнулся еще с проблемой такой, что остаются следы после передвижения и именно от линий. Вот когда баловался выводил окружность, эллипс и двигал все нормально, как только появляются линии. при движении остаются следы, будто не стирается. Вот на примере выше, бабочка еще нормально, но шестиугольник и комбинированная фигура. при движении оставляет следы. В чем проблема и как от нее избавиться?
Вот кстати, без виртуального наследования следы однозначно будут оставаться при движении объекта типа Combo. Причем не только от линий, а и от эллипсов, то есть, объект будет просто напросто некорректно перерисовываться. Именно потому, что не надо второй раз инициализировать Figure... Рисоваться и стираться будут разные объекты. Как только ты сделаешь наследование виртуальным - этот глюк пропадет, объект Figure останется только один...
А насчет как избавиться от следов линий - не знаю, Wine запускать лениво, да и компилятор TurboC я уже стер... Теоретически - если ты уверен, что это линии "недоудаляются" - попробуй при стирании ставить бОльшую толщину линии (не NORM_WIDTH, который 1, как обычно, а THICK_WIDTH, который = 3). То есть, перед удалением установи через setlinestyle толстую линию, а потом, перед отрисовкой - опять обычную, узкую...
IUnknown, добавил виртуальное наследование к бабочке и шестиугольнику, но компилятор ругается в конструкторе Combo на то что не найден конструктор для инициализации базового класса Figure (с английским у меня плохо, но что то в этом роде)
class base {
// ...
};
class A : public base {
// ... тут инициализируется базовый класс
};
class B : public base {
// ... и тут инициализируется базовый класс
};
class C : public A, public B {
// Здесь достаточно инициализировать прямых предков, но не ИХ предков
C() : A(), B() {}
// ...
};
class Combo : public Hexe, public Butterfly
{
public:
Combo(int iCenterX, int iCenterY, int iStangle, int iEndangle, int iRadiusX, int iRadiusY, int iRadius) :
Hexe(iCenterX, iCenterY, iRadius),
Butterfly(iCenterX, iCenterY, iStangle, iEndangle, iRadiusX, iRadiusY, iRadius),
Figure(iCenterX, iCenterY)
{}
// ...
Очередной раз спасибо за разъяснение. Учусь на заочном отделении, а там преподаватели не учат, а в лучшем случае если повезет могут дать консультацию.