Допустим, нам надо создать класс, который включал бы структуры других классов. Допустим, у нас есть классы Point, Color, Length. Создадим класс Circle, который по сути будет являться набором из этих классов.
class Point
{
protected:
int x,y;
public:
Point ():x(50),y(50) {}
Point (int nx,int ny):x(nx),y(ny) {}
void Show()
{
cout<<"Coord: ("<<x<<","<<y<<")"<<endl;
}
};
class Color
{
protected:
int color,colorfill;
public:
Color ():color(0),colorfill(0) {}
Color (int ncolor, int ncolorfill):color(ncolor),colorfill(ncolorfill) {}
void Show()
{
cout<<"Colors: "<<color<<","<<colorfill<<endl;
}
};
class Length
{
protected:
int len;
public:
Length():len(0) {}
Length(int nlen):len(nlen) {}
void Show()
{
cout<<"Length:"<<len<<endl;
}
};
class Circle
{
public:
Point coord;
Color color;
Length radius;
Circle (int nx,int ny,int ncolor,int ncolorfill,int nrad):
coord(Point(nx,ny)),
color(Color(ncolor,ncolorfill)),
radius(Length(nrad)) {}
void Show()
{
this->coord.Show();
this->color.Show();
this->radius.Show();
}
};
void main()
{
Circle *circ=new Circle(100,100,2,5,50);
circ->Show(); //
cout<<"\n";
//т. к. у нас объекты других классов объявлены в зоне public, то возможно и такое //обращение
circ->coord.Show();
circ->color.Show();
circ->radius.Show();
//далее, нам остается только удалить созданный объект
delete circ;
}
В этом примере, у нас некорректно работает функция Length::Show(), т. к. она нам показывает радиус окружности как длину, со словом «Length». Чтобы разрешить это противоречие, нам нужно переписать реализацию функции Show().
void Show()
{
this->coord.Show();
this->color.Show();
cout<<"Radius:"<<this->radius.len;
}
Здесь мы снова сталкиваемся с проблемой. Это уже не наследование, это включение, а свойство Length::len у нас объявлено в зоне protected, т. е. оно доступно для производных классов, но для объектов класса, в нашем случае это Length radius это свойство недоступно.
Выходов может быть два: переместить свойство в зону public, либо написать метод класса Length, который будет возвращать это свойство, и его уже использовать во время вывода.
В зону public, класса Length добавим прототип функции:
int Get();
И опишем саму функцию вне класса:
int Length::Get()
{
Return this->len;
}
Тогда функция вывода изменится следующим образом
void Show()
{
this->coord.Show();
this->color.Show();
cout<<"Radius:"<<this->radius.Get();
}
Еще стоит добавить, что объекты, создаваемые внутри класса следует создавать тоже динамически, и освободить память, когда они станут не нужны.
Тогда реализация класса Circle будет выглядеть так:
class Circle
{
public:
Point *coord;
Color *color;
Length *radius;
Circle (int nx,int ny,int ncolor,int ncolorfill,int nrad):
coord(new Point(nx,ny)),
color(new Color(ncolor,ncolorfill)),
radius(new Length(nrad)) {}
void Show()
{
this->coord->Show();
this->color->Show();
this->radius->Show();
}
~Circle()
{
delete coord;
delete color;
delete radius;
}
};
void main()
{
Circle *circ=new Circle(100,100,2,5,50);
circ->Show();
delete circ;
_getch();
}
Здесь, при удалении объекта, связанного с указателем circ, предварительно произойдет удаление объектов, созданных непосредственно внутри класса Circle. В классе у нас уже не объекты, а ссылки на вновь созданные объекты, что ведет к изменению способа обращения в функции Show().