printКлассы

printОпределение и вызов методов. Указатель 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 и итераторы (указатели на элементы в контейнере).
loading