4. Обекти

 
"Съществуват обекти, които не  могат да бъдат
изчерпателно описани или обяснени.
При теолозите такъв обект е Бог."
Станислав Лем
 
Конструиране на обекти.
    Обектът е стойност, която може да се създава, запазва и обработва със средствата на езика за програмиране. Обект = променлива или константа, като понятието обект се използва за "по-големи" променливи или константи. Например
 int k = 1;               /* k е обект, по-добре променлива */
 string greeting = "Hello"; /* greeting и "Hello" са обекти */
 * Тип данни клас. Класовете се дефинират от програмиста. Класът Time е дефиниран от К. Хорстман в [1]. Обект от този клас ще съхранява момент от времето - час, минути, секунди.
 * Конструиране на обект. Time(23,59,59) означава 23 часа, 59 минути и 59 секунди. Това е обект-константа, аналогичен на числовите константи (числата) и низовете, напр. "Hello".
 * Включване на файл с дефиниция на класа:
    #include "ccc_time.cpp"
 * Дефиниране на променлива (обект) от тип Time:
        Time day_end = Time(23,59,59);
или по-кратко (съкратен запис):
    Time day_end(23,59,59);
Името на променливата е day_end, типът на променливата е Time и началната стойност на променливата е Time(23,59,59).
 * Конструктор и параметри на конструктора.
   За създаване на обекти от клас се използва функция, наречена конструктор на класа:
-- името на конструктора съвпада с името на класа;
-- параметрите на конструктора са зададени в дефиницията на класа.
 * Конструиране по подразбиране.
   Задаване на текущото време по компютърния часовник (в момента на изпълнение на програмата):
       Time now = Time();
или съкратено:
   Time now;


Използване на обекти.
* Член-функции на класа:
   Time wake_up(7,0,0);       /* 7:00:00 */
   wake_up.add_seconds(1000); /* 7:16:40 */
Добавя 1000 секунди към момента от време, записан в обекта wake_up.
 * Функции на класа Time:
 
 Име  Действие
Time() Конструира обект, показващ текущото време
Time(h,m,s) Конструира обект, показващ h часа, m минути и s секунди
t.get_seconds() Връща броя на секундите в t.
t.get_minutes() Връща броя на минутите в t.
t.get_hours() Връща броя на часовете в t.
t.add_seconds(n) Премества t с n секунди напред.
t.seconds_from(t2)  Пресмята броя на секундите между t  и t2.

Колко секунди остават до края на деня?
// time2.cpp
#include <iostream>
using namespace std;
#include "ccc_time.cpp"

int main()
{ Time now;
  Time day_end(23, 59, 59);
  long seconds_left = day_end.seconds_from(now);
  cout << "There are " << seconds_left
      << " seconds left in this day.\n";
  return 0;
}

There are 44219 seconds left in this day.

     Тъй като денонощието съдържа 24x3600 = 86400 секунди, член-функцията seconds_from връща стойност от тип long.



Обекти от реалния свят.
    Обект от тип Employee (служител) ще съхранява име на служител и неговата (годишна) заплата. В програмата се създава обект harry с начална заплата 45000 и след това му се повишава заплатата с още 3000.
// employee.cpp
#include <iostream>
using namespace std;
#include "ccc_empl.cpp"

int main()
{  Employee harry("Hacker, Harry", 45000.00);
   double new_salary = harry.get_salary() + 3000;
   harry.set_salary(new_salary);
   cout << "Name: " << harry.get_name() << "\n";
   cout << "Salary: " << harry.get_salary() << "\n";
   return 0;
}

Name: Hacker, Harry
Salary: 48000

В таблицата са дадени всички член-функции, дефинирани в класа Employee:
 

Име Действие
Employee(n,s) Конструира обект, представящ служител с име n и заплата s.
e.get_name() Връща името на e.
e.get_salary() Връща заплатата на e.
e.set_salary(s)  Дава нова стойност s на заплатата на e.

Графични форми. Графични класове.
** Изобразяване на графични форми.
    В зависимост от организацията на входа и изхода в С++ се различават два типа програми - текстови приложения и графични приложения. Текстовите приложения приемат вход от клавиатурата (чрез cin) и извеждат текст на екрана (чрез cout). Използва се текстов екран (конзола), като текстът се разполага (най-често) на 25 реда по 80 символа на ред. Графичните програми приемат вход от клавиатура и мишка и извеждат графични форми (напр. точки и окръжности) на  графичен екран (в нашия случай чрез обекта cwin). На графичния екран (прозорец) има дефинирана координатна система и обектите се разполагат по зададени координати.
    К. Хорстман създава малка графична библиотека, дефинирана във файла ccc_win.cpp с обекти:
 -- Точка:  Point(3,1)
#include "ccc_win.cpp"
int main()
{  cwin << Point(3,1);
   return 0;
}
 -- Окръжност: Circle(Point(2,3),1)
#include "ccc_win.cpp"
int main()
{  Point p(1, 3);
   cwin << p << Circle(p, 2.5);
   return 0;
}
 -- Отсечка: Line(Point(1,3), Point(2,2))
#include "ccc_win.cpp"
int main()
{ Point p(1, 3);
  Point q(4, 7);
  Line s(p, q);
  cwin << s;
  return 0;
}
 -- Текст: Message(Point(4,4),"Hello")
#include "ccc_win.cpp"
int main()
{  Point p(1, 3);
   Message greeting(p, "Hello, Window!");
   cwin << greeting;
   return 0;
}

Следват таблици с всички дефинирани член-функции в графичните класове.
 
 

Име Действие
Point p=Point(x,y); Конструира точка p с координати(x,y).
p.get_x() Връща x-координатата на точката p
p.get_y() Връща y-координатата на точката p.
p.move(dx,dy) Премества точката p с (dx,dy).

 
Име Действие
Circle c=Circle(p,r);  Конструира окръжност с център p и радиус r.
c.get_center() Връща центъра p на окръжността c.
c.get_radius() Връща радиуса r на окръжността c.
c.move(dx,dy) Премества окръжността c с (dx,dy).

 
Име Действие
Line l=Line(p,q);  Конструира отсечка l, свързваща точките p и q.
l.get_start() Връща началната точка p на отсечката l.
l.get_end() Връща крайната точка q на отсечката l
l.move(dx,dy) Премества отсечката l с (dx,dy).

 
Име Действие
Message m=Message(p,s);  Конструира съобщение m с начална точка p и съдържание s.
Message m=Message(p,x);  Конструира съобщение m с начална точка p и етикет числото x.
m.get_start() Връща началната точка p на съобщението m.
m.get_text() Връща съдържанието s на съобщението m.
m.move(dx,dy) Премества съобщението m с (dx,dy).

Избор на координатна система.
    По подразбиране центърът на координатната система на графичния прозорец е в центъра на прозореца, като координатите на горния ляв ъгъл  са -10,10, а на долния десен ъгъл 10,-10:
  cwin.coord(-10,10,10,-10);
Програмистът може да зададе нова координатна система като посочи координатите на двете точки - горен ляв и долен десен ъгъл. Например
горения ляв ъгъл:  0,100 и долен десен ъгъл: 50,0.
  cwin.coord(0,100,50,0);



Получаване на вход от графичния прозорец.
string name = cwin.get_string("Моля, въведете своето име: ");
Point center = cwin.get_mouse("Enter center of the circle");
    В следващия пример програмата пита за име и след това въведеното име се извежда в графичния прозорец на зададено с мишката място.
// click.cpp
#include "ccc_win.cpp"

int main()
{ string name = cwin.get_string("Please type your name:");
  Circle c(Point(0, 0), 1);
  cwin << c;
  Point m = cwin.get_mouse("Please click inside the circle.");
  cwin << m << Message(m, name + " clicked here");
  return 0;
}

Име Действие
 win.coord(x1,y1,x2,y2)  Избира координатна система.
 win << x Изобразява обекта  x в прозореца.
 win.clear() Изчиства прозореца win.
 win.get_string(p) Извежда подканващ текст p и връща въведения низ
 win.get_int(p) Извежда подканващ текст p и връща въведеното цяло число
 win.get_double(p) Извежда подканващ текст p и връща въведеното число с плаваща точка

 
win.get_mouse(p) Извежда подканващ текст p и връща точката, избрана с мишката

Сравняване на визуална и числова информация.
    Намиране на пресечни точки на права и окръжност. Окръжността е с център началото на координатната система и зададен радиус - radius. Правата е успоредна на абсцисната ос и е на зададено разстояние b от нея. Чертаем двата графични обекта и още две точки, получени от пресмятането на пресечните точки на правата и окръжността. Ако пресмятанията са верни, двете точки трябва да се появят точно на местата на пресичане на двете графични форми.
// intersect2.cpp
#include "ccc_win.cpp"

int main()
{  double radius = cwin.get_double("Radius: ");
   Circle c(Point(0, 0), radius);
   double b = cwin.get_double("Line position: ");
   Line s(Point(-10, b), Point(10, b));
   cwin << c << s;
   double root = sqrt(radius * radius - b * b);
   Point p1(root, b);
   Point p2(-root, b);
   Message m1(p1, p1.get_x());
   Message m2(p2, p2.get_x());
   cwin << p1 << p2 << m1 << m2;
   return 0;
}
Какво става, ако правата не пресича окръжността?