Перегруженный оператор “стрелка” должен возвращать либо указатель на тип класса, либо объект класса, в котором он определен. Если возвращается указатель, то к нему применяется семантика встроенного оператора “стрелка”. В противном случае процесс продолжается рекурсивно, пока не будет получен указатель или определена ошибка. Например, так можно воспользоваться объектом ps класса ScreenPtr для доступа к членам Screen:
ps->move( 2, 3 );
Поскольку слева от оператора “стрелка” находится объект типа ScreenPtr, то употребляется перегруженный оператор этого класса, который возвращает указатель на объект Screen. Затем к полученному значению применяется встроенный оператор “стрелка” для вызова функции-члена move().
Ниже приводится небольшая программа для тестирования класса ScreenPtr. Объект типа ScreenPtr используется точно так же, как любой объект типа Screen*:
#include <iostream>
#include <string>
#include "Screen.h"
void printScreen( const ScreenPtr &ps )
{
cout << "Screen Object ( "
<< ps->height() << ", "
<< ps->width() << " )\n\n";
for ( int ix = 1; ix <= ps->height(); ++ix )
{
for ( int iy = 1; iy <= ps->width(); ++iy )
cout << ps->get( ix, iy );
cout << "\n";
}
}
int main() {
Screen sobj( 2, 5 );
string init( "HelloWorld" );
ScreenPtr ps( sobj );
// Установить содержимое экрана
string::size_type initpos = 0;
for ( int ix = 1; ix <= ps->height(); ++ix )
for ( int iy = 1; iy <= ps->width(); ++iy )
{
ps->move( ix, iy );
ps->set( init[ initpos++ ] );
}
// Вывести содержимое экрана
printScreen( ps );
return 0;
}
Разумеется, подобные манипуляции с указателями на объекты классов не так эффективны, как работа со встроенными указателями. Поэтому интеллектуальный указатель должен предоставлять дополнительную функциональность, важную для приложения, чтобы оправдать сложность своего использования.