main.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Темы:
  2. // Простое наследование. Виртуальные функции. Абстрактные классы.
  3. // Битовые поля.
  4. #include "General.h"
  5. #include <iostream>
  6. #include <tchar.h>
  7. #define stop __asm nop
  8. int _tmain(int argc, _TCHAR* argv[])
  9. {
  10. //Задание 1.Массив объектов класса.
  11. {
  12. //Объявите и проинициализируйте массив ar из объектов типа MyString.
  13. //Замените размер const int N=5; , не изменяя список инициализаторов.
  14. //const int N=3;
  15. const int N = 5;
  16. MyString str1[N] = { MyString("First"), MyString("Second"), MyString("Third")};
  17. //Проверка - печать строк-членов класса
  18. for (int i = 0; i < N; i++)
  19. {
  20. std::cout << str1[i].GetString() << std::endl;
  21. }
  22. }
  23. stop
  24. //Задание 2.Массив указателей на объекты класса.
  25. {
  26. //Объявите и проинициализируйте массив arPtr из N
  27. //указателей на объекты типа MyString (сами объекты создаются динамически!).
  28. //Замените размер const int N=5; , не изменяя список инициализаторов.
  29. //const int N=3;
  30. const int N = 5;
  31. MyString* arPtr[N] = { new MyString("First ptr"), new MyString("Second ptr"), new MyString("Third ptr") };
  32. //Печать строк-членов класса
  33. for (int i = 0; i < N; i++)
  34. {
  35. if(arPtr[i])
  36. {
  37. std::cout << (*arPtr[i]).GetString() << std::endl;
  38. }else{ std::cout << "nullptr - Empty string" << std::endl; }
  39. }
  40. }
  41. stop
  42. //Задание 3.Простое наследование.Аргументы конструктора,
  43. // передаваемые в базовый класс.
  44. //Создайте иерархию классов:
  45. //базовый класс Shape (который описывает любую фигуру)
  46. //и два производных класса Rect и Circle.
  47. //Подумайте: какие данные и методы нужно ввести в базовый
  48. //и производные классы (например, любую фигуру можно сделать
  49. //цветной => в базовом классе можно ввести переменную, которая
  50. //будет определять цвет фигуры.
  51. //Подсказка: для хранения цвета объявите перечисление (RED,GREEN,BLUE...);
  52. //В конструкторах производных классов предусмотрите передачу
  53. //параметра-цвета конструктору базового класса.
  54. //При создании и уничтожении объекта производного типа определите
  55. //последовательность вызовов конструкторов и деструкторов базового
  56. //и производного классов
  57. Shape Shape1;
  58. Shape Shape2(RED);
  59. Rect Rect1;
  60. Rect Rect2(1);
  61. Rect Rect3(1,2,3,4);
  62. Rect Rect4(1, 2, 3, 4, GREEN);
  63. Circle Circle1;
  64. Circle Circle2(5);
  65. Circle Circle3(5, 3, 1, BLUE);
  66. stop
  67. //////////////////////////////////////////////////////////////////////
  68. //Задание 4.Виртуальные функции.
  69. //4а) Модифицируйте классы Shape,Rect и Circle:
  70. //добавьте в каждый класс public метод void WhereAmI().
  71. //Реализация каждой функции должна выводить сообщение
  72. //следующего вида "Now I am in class Shape(Rect или Circle)".
  73. //Выполните приведенный фрагмент, объясните результат.
  74. {
  75. Shape s(RED);
  76. Rect r(1, 2, 3, 4, GREEN);
  77. Circle c(5, 3, 1, BLUE);
  78. //Метод какого класса вызывается в следующих строчках???
  79. s.WhereAmI(); // Shape (вызов формируется на этапе компиляции, как для обычного метода класса)
  80. r.WhereAmI(); // Rect
  81. c.WhereAmI(); // Circle
  82. stop
  83. Shape* pShape = &s;
  84. Shape* pRect = &r;
  85. Shape* pCircle = &c;
  86. pShape->WhereAmI(); // Shape (раннее связывание, т.к. указатель базового типа, во всех случаях будет вызван метод базового класса)
  87. pRect->WhereAmI(); // Shape (не имеет значение какого типа объект)
  88. pCircle->WhereAmI(); // Shape
  89. stop
  90. //Заполните ... согласно комментариям
  91. Shape& rShape = s; //псевдоним s (тип переменной Shape&)
  92. Shape& rRect = r; //псевдоним r
  93. Shape& rCircle = c; //псевдоним c
  94. rShape.WhereAmI(); //вызов посредством rShape Shape
  95. rRect.WhereAmI(); //вызов посредством rRect Shape
  96. rCircle.WhereAmI(); //вызов посредством rCircle Shape
  97. stop
  98. }
  99. //4б) Добавьте в базовый и производные классы виртуальный
  100. // метод WhereAmIVirtual(). По аналогии с 4а вызовите
  101. // виртуальный метод посредством объектов, указателей и
  102. // ссылок, определенных в предыдущем фрагменте.
  103. //Выполните новый фрагмент, объясните разницу.
  104. {
  105. Shape s(RED);
  106. Rect r(1, 2, 3, 4, GREEN);
  107. Circle c(5, 3, 1, BLUE);
  108. //Метод какого класса вызывается в следующих строчках (вызов формируется на этапе компиляции, как для обычного метода класса)
  109. s.WhereAmIVirtual(); // Shape
  110. r.WhereAmIVirtual(); // Rect
  111. c.WhereAmIVirtual(); // Circle
  112. stop
  113. Shape* pShape = &s;
  114. Shape* pRect = &r;
  115. Shape* pCircle = &c;
  116. pShape->WhereAmIVirtual(); // Shape (косвенно, посредством таблицы виртуальных функций)
  117. pRect->WhereAmIVirtual(); // Rect
  118. pCircle->WhereAmIVirtual();// Circle
  119. stop
  120. //Заполните ... согласно комментариям
  121. Shape& rShape = s; //псевдоним s
  122. Shape& rRect = r; //псевдоним r
  123. Shape& rCircle = c; //псевдоним c
  124. rShape.WhereAmIVirtual(); //вызов посредством rShape Shape (косвенно, посредством таблицы виртуальных функций)
  125. rRect.WhereAmIVirtual(); //вызов посредством rRect Rect
  126. rCircle.WhereAmIVirtual(); //вызов посредством rCircle Circle
  127. stop
  128. }
  129. //////////////////////////////////////////////////////////////////////
  130. //Задание 5.Виртуальные деструкторы.
  131. //Модифицируйте классы:
  132. //a) введите соответствующие
  133. // деструкторы (без ключевого слова virtual).
  134. //Реализация каждого деструктора
  135. //должна выводить сообщение следующего вида
  136. // "Now I am in Shape's destructor!" или
  137. // "Now I am in Rect's destructor!"
  138. //Выполните фрагмент. Объясните результат.
  139. // b) Добавьте в объявление деструкторов ключевое слово virtual
  140. //Выполните фрагмент.Объясните разницу.
  141. //Подумайте: какие конструкторы вызываются в следующей строке?
  142. //Если в разработанных классов каких-то конструкторов
  143. //не хватает - реализуйте
  144. //Если Вы считаете, что в приведенном фрагменте чего-то
  145. //не хватает - добавьте
  146. Rect r(1,2,3,4);
  147. Shape* ar[]={new Shape(r), new Rect(r), new Circle(r), new Circle()};
  148. //Вызовите для каждого элемента массива метод WhereAmIVirtual()
  149. for (int i = 0; i < (sizeof(ar) / sizeof(ar[0])); i++)
  150. {
  151. ar[i]->WhereAmIVirtual();
  152. delete ar[i];
  153. }
  154. stop
  155. //Задание 6*. В чем заключается отличие 1) и 2)
  156. {
  157. Shape* pShapes = new Rect[10];//1) одномерный динамический массив указателей типа Shape на обьекты типа Rect
  158. Rect* pRects = new Rect[10];//2) одномерный динамический массив указателей типа Rect на обьекты типа Rect
  159. //Попробуйте вызвать метод WhereAmIVirtual() для каждого элемента обоих массивов -
  160. //в чем заключается проблема???
  161. for (int i = 0; i < 10; i++)
  162. {
  163. pRects[i].WhereAmIVirtual();
  164. }
  165. /*
  166. for (int i = 0; i < 10; i++)
  167. {
  168. pShapes[i].WhereAmIVirtual(); //проблема на второй итерации, указатель базового класса, сдвиг???
  169. }
  170. */
  171. //Освободите динамически захваченную память
  172. delete []pShapes; //неверный сдвиг, могут быть нюансы
  173. delete[]pRects;
  174. }
  175. //////////////////////////////////////////////////////////////////////
  176. //Задание 7.Виртуальные функции и оператор разрешения области видимости.
  177. {
  178. Rect r(1,2,3,4);
  179. Shape* p = &r;
  180. p->WhereAmIVirtual();//Rect
  181. stop
  182. //4a Оператор разрешения области видимости.
  183. //Посредством объекта r и указателя p вызовите виртуальную функцию
  184. //WhereAmIVirtual()класса Shape
  185. p->Shape::WhereAmIVirtual();//Shape
  186. stop
  187. }
  188. //////////////////////////////////////////////////////////////////////
  189. //Задание 8.Чисто виртуальные функции.
  190. //Введите в базовый класс метод void Inflate(int); Подумайте:
  191. //можно ли реализовать такой метод для базового класса? => как его нужно объявить.
  192. //Реализуйте этот метод для производных классов.
  193. {
  194. Rect r(1,2,3,4);
  195. Shape* p = &r;
  196. p->Inflate(5);
  197. Circle c(1,2.3);
  198. p = &c;
  199. p->Inflate(5);
  200. }
  201. //////////////////////////////////////////////////////////////////////
  202. //Задание 9. Создайте глобальную функцию, которая будет принимать любое
  203. //количество указателей на строки, а возвращать объект MyString,
  204. //в котором строка будет конкатенацией параметров
  205. MyString res = concatenation("hello","i'm","Svetlana",nullptr);
  206. stop
  207. ////////////////////////////////////////////////////////////////////////
  208. /*
  209. //Задание 10.Объединения (union) C++. Битовые поля.
  210. //1.
  211. //Создайте следующие классы для различных представлений значений байта:
  212. //Bin - для двоичного представления
  213. //Hex - для шестнадцатерчного представления
  214. //Oct - для восьмеричного представления.
  215. //Подсказка 1: - для удобства используйте битовые поля.
  216. //Подсказка 2: - конструкторов в таких вспомогательных классах быть не должно,
  217. //так как все они будут членами объединения (union).
  218. //2.
  219. //В каждом классе введите метод Show, который должен выводить значение в
  220. //соответствующем виде
  221. //3.
  222. //Посредством объединения MyByte предоставьте пользователю возможность манипулировать
  223. //одним и тем же значением по-разному:
  224. //а) выводить: десятичное, шестнадцатеричное, восьмеричное, двоичное значение байта
  225. // а также символ, соответствующий хранимому значению (если есть соответствие);
  226. //б) выводить отдельные (указанные посредством параметра) шестнадцатеричные,
  227. // восьмеричные, двоичные цифры;
  228. //в) изменять отдельные двоичные, восьмеричные или шестнадцатеричные цифры;
  229. MyByte byte(0x1f);
  230. byte.ShowHex();
  231. byte.ShowBin();
  232. //...
  233. */
  234. return 0;
  235. }//endmain