Void cure(int health, int ammo)

{

this-> health+=health; /* использование this */

monstr::ammo+=ammo; /* использование операции:: */

}

Использование параметра this не дает ощутимого преимущества при программировании, так как данные конкретного объекта уже доступны в принадлежащих классу функциях по именам. Удобным и необходимым он становится, когда в теле принадлежащей классу функции требуется явно задать адрес, для которого она была вызвана.

Ниже приведён пример кода, в котором использование this делает код более читаемым и удобным для написания.

Пример 2

class MyClass{

void foo(){

   MyClass *ptr = new MyClass(*this);

       //Тут некоторый код

   delete ptr;

}

};

int main(){

 MyClass obj;

}

Без указателя this этот код выглядел бы примерно так:

Пример 3

class MyClass{

void foo(MyClass* obj){

   MyClass *ptr = new MyClass(*obj);

       //Тут некоторый код

   delete ptr;

}

public:

void init(MyClass* obj){

   foo(obj);

}

};

 

int main(){

 MyClass obj;

 obj.init(&obj);

}


 


Статические элементы классов

Статическими компонентами называются компоненты класса, которые объявлены с модификатором static. Статические компоненты класса являются частью класса, но не включаются в объекты этого класса. Имеется ровно одна копия статических полей класса. Она является общей для всех объектов данного класса. Статические поля никогда не дублируются.

Особенности:

память под статические поля выделяется один раз при их инициализации. Независимо от числа созданных объектов (и даже при их отсутствии) инициализируются статические поля с помощью операции доступа к области действий, а не с помощью оператора выбора (т.е. определение статического поля должно быть описано вне функции).

Пример 1

Class A

{

public:

static int count; /* Объявление в классе */

};

int A::count; /* Объявление в глобальной области. По умолчанию инициализируется нулем */

int A::count = 10; /* Пример инициализации произвольным значением */

Статические поля доступны как через имя класса, так и через имя объекта.

Пример 2

A*a,b;

cout<<A::count<<a->count<<b.count;

 

На статические поля распространяется действие спецификаторов доступа, следовательно описанные как private статические поля нельзя изменять с помощью операций доступа к области действия. Это можно сделать только с помощью статических методов. Память, занимаемая статическим полем, не учитывается при определении размера объекта с помощью операции sizeof. Принципиально любой метод класса может обратиться к статическому полю и изменить его значение. Но существует возможность обращения к статическому полю при отсутствии объектов данного класса. Такой доступ осуществляется с помощью статических компонентных функций, которые объявляются со спецификатором static. Статическая функция не ассоциируется с каким-либо объектом и не получает параметра this. Она не может без указателя объекта обращаться к нестатическим полям класса. При необходимости ссылка на конкретный объект может быть передана в списка параметров и тогда статическая функция может обратиться к нестатическим полям следующим образом:

<имя объекта>.<имя нестатического поля класса>

При обращении к статическому компоненту класса, являющемуся принадлежностью всех объектов данного класса, можно вместо имени объекта указать имя класса.

<класс>::<компонент>


 


Статические методы

Предназначены для обращения к статическим полям класса. Обращение к статическим методам производится так же, как и к статическим полям, а именно:

а) через имя класса,

б) через имя объекта, если он уже создан.

Пример 1

Class A

{

static int count; /* поле count - скрытое */

public:

static void int_count() {count++}

};

A::int count; /* определение в глобальной области*/

Void f()

{

A.a;

/* a.count++ - нельзя, так как поле count скрытое.

Изменение поля count выглядит следующим образом: */

a.inc_count();

/*или:*/

A::inc_count();

}

Пример 2

Class point

{

int x, y, color; /* нестатическое поле */

static int obj_count; /* Статическое поле - счетчик обращений */

public:

point();

static void draw_point(point &p); /* статическая функция */

};

int point::obj_count = 0; /* инициализация статического поля */

void point::draw_point(point &p) /* имя объекта передано в списке параметров */

{

putpixel(p.x, p.y, p.color);

obj_count++; /* обращение к статическому и нестатическому полю */

}


 


Рекомендации по составу класса

Класс, как тип, определяемый пользователем, должен содержать скрытые поля (private) и следующие функции:

· конструкторы, определенные как инициализирующиеся объекты класса;

· методы, реализующие свойства класса (методы, возвращающие значения скрытых полей класса описываются с модификатором const, который указывает, что они не должны изменять значения этих полей);

· операции, позволяющие копировать, присваивать, сравнивать объекты и производить над ними другие действия, требуемые по сути класса;

· необходим еще функциональный класс исключений, используемый для сообщений об ошибках, с помощью генерации исключительных ситуаций.

Могут также использоваться функции, которые работают с классом или несколькими классами через интерфейс (т.е. доступ к скрытым полям им не требуется). Эти функции можно описать вне классов, чтобы не перегружать интерфейс. Чтобы обеспечить логическую связь, можно поместить их в общее с этим классом пространство имен.

Пример 1

Namespace staff

{

class monstr{...};

class hero{...};

void interact(hero, monstr);

}

Пример 2

class String {

 public:

// набор конструкторов

// для автоматической инициализации

// String strl;         // String()

// String str2("literal"); // String(const char*);

// String str3(str2); // String(const String&);

 

String();

String(const char*);

String(const String&);

 

// деструктор

~String();

 

// операторы присваивания

// strl = str2

// str3 = "a string literal"

 

String& operator=(const String&);

String& operator=(const char*);

 

// операторы проверки на равенство

// strl == str2;

// str3 == "a string literal";

 

bool operator==(const String&);

bool operator==(const char*);

 

// перегрузка оператора доступа по индексу

// strl[ 0 ] = str2[ 0 ];

 

char& operator[](int);

 

// доступ к членам класса

int size() { return _size; }

char* c_str() { return _string; }

 

 private:

int _size;

char *_string;

 }


 


Глава 4. Дружественные классы и функции


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: