• Если объект передается объекту класса Vector_ref
с помощью ссылки, то предполагается, что он принадлежит вызывающей функции, которая управляет его временем жизни (например, объект — это переменная, находящаяся в определенной области видимости).
• Если объект передается объекту класса Vector_ref
с помощью указателя, то предполагается, что он размещен в памяти с помощью оператора new
, а ответственность за его удаление несет класс Vector_ref
.
Элемент хранится в объекте класса Vector_ref
в виде указателя, а не как копия объекта, и имеет семантику ссылок. Например, можно поместить в вектор класса Vector_ref
объект класса Circle
, не подвергаясь опасности срезки.
template
vector
vector
public:
Vector_ref() {}
Vector_ref(T* a, T* b = 0, T* c = 0, T* d = 0);
~Vector_ref() { for (int i=0; i
delete owned[i]; }
void push_back(T& s) { v.push_back(&s); }
void push_back(T* p) { v.push_back(p); owned.push_back(p); }
T& operator[](int i) { return *v[i]; }
const T& operator[](int i) const { return *v[i]; }
int size() const { return v.size(); }
};
Деструктор класса Vector_ref
удаляет каждый объект, переданный ему как указатель.
Д.5. Пример: манипулирование объектами класса Widget
Это законченная программа. Она демонстрирует многие из свойств классов Widget/Window
. Мы поместили в нее минимальное количество комментариев. К сожалению, такое недостаточное комментирование программ — довольно распространенное явление. Попытайтесь выполнить эту программу и объяснить, как она работает.
#include "../GUI.h"
using namespace Graph_lib;
class W7 : public Window {
// четыре способа продемонстрировать, что кнопка может
// передвигаться:
// показать/скрыть, изменить местоположение, создать новую
// и присоединить/отсоединить
public:
W7(int n, int n, const string& t);
Button* p1; // показать/скрыть
Button* p2;
bool sh_left;
Button* mvp; // переместить
bool mv_left;
Button* cdp; // создать/уничтожить
bool cd_left;
Button* adp1; // активировать/деактивировать
Button* adp2;
bool ad_left;
void sh(); // действия
void mv();
void cd();
void ad();
static void cb_sh(Address, Address addr) // обратные вызовы
{ reference_to
static void cb_mv(Address, Address addr)
{ reference_to
static void cb_cd(Address, Address addr)
{ reference_to
static void cb_ad(Address, Address addr)
{ reference_to
};
Однако объект класса W7
(эксперимент с объектом класса Window
номер 7
) на самом деле содержит шесть кнопок: просто две из них он скрывает.
W7::W7(int w, int h, const string& t)
:Window(w,h,t),
sh_left(true),mv_left(true),cd_left(true),ad_left(true)
{
p1 = new Button(Point(100,100),50,20,"show",cb_sh);
p2 = new Button(Point(200,100),50,20,"hide",cb_sh);
mvp = new Button(Point(100,200),50,20,"move",cb_mv);
cdp = new Button(Point(100,300),50,20,"create",cb_cd);
adp1 = new Button(Point(100,400),50,20,"activate",cb_ad);
adp2 = new Button(Point(200,400),80,20,"deactivate",cb_ad);
attach(*p1);
attach(*p2);
attach(*mvp);
attach(*cdp);
p2–>hide();
attach(*adp1);
}