Определение и вызов методов. Указатель this
Объявление класса обычно помещается в заголовочном файле (.h), а сами
методы определяются в файле реализации (.cpp). Определения простых методов можно поместить в объявление класса, в этом случае они будут считаться определенными со спецификатором
inline. При определении методов вне интерфейса класса непосредственно перед именем метода необходимо указать имя класса и символы
::
Пример объявления класса:
constexpr int Stack_size=100; //
class Stack {
int s[Stack_size];
int t;
public:
void clear() { t=-1; } //
bool isEmpty() { return t==-1; }
bool isFull() { return t==Stack_size-1; }
void pop();
int top();
void push(int);
};
class StackEmpty {}; //
class StackFull {};
Реализация методов класса:
void Stack::pop()
{ if(!isEmpty())
--t;
}
int Stack::top()
{ if(isEmpty())
throw StackEmpty(); //
return s[t];
}
void Stack::push(int v)
{ if(isFull())
throw StackFull(); //
s[++t]=v;
}
При
вызове метода сначала указывают имя объекта, затем после точки указывают имя метода и список аргументов в скобках. При использовании указателя на объект, вместо точки используют операцию
->
Пример вызова методов:
int main()
{
Stack s1;
s1.clear();
s1.push(10);
cout<<s1.top()<<"\n";
s1.pop();
...
Stack *s2;
s2=new Stack;
s2->clear();
s2->push(10);
cout<<s2->top()<<"\n";
s2->pop();
...
}
Адрес объекта, к которому примеряется метод, передается с помощью скрытого параметра и доступен внутри метода под именем
this. С помощью указателя
this можно также обратиться к полю при совпадении имени поля и имени параметра метода. Другой вариант решения этой проблемы – написать имя класса и
:: перед именем поля.
struct time {
int h,m;
void set(int h, int m)
{
this->h=h;
time::m=m;
}
};
В С++23 скрытый параметр можно указать явно в списке параметров функции и дать ему имя, при этом можно выбрать способ передачи параметра (по ссылке, по указателю, по значению и добавить const):
struct Point {
double x,y;
Point& add(this Point& self, Point p) { self.x+=p.x; self.y+=p.y; return self; }
double len(this Point self) { return hypot(self.x,self.y); }
};
Таким образом можно окончательно избавиться от обычных указателей в С++, и остаются только их более умные аналоги –-
unique_ptr,
shared_ptr и итераторы (указатели на элементы в контейнере).