Программирование >>  Программирование на языке c++ 

1 ... 67 68 69 [ 70 ] 71 72 73 ... 159


virtual .void operator()() { cout n A objects\n ; }

class В : public A {

static m; public:

B() { m++; } конструктор производного класса void operatorOO { cout m B obiects\n ; }

int A::n=0; инициализация статических переменных int B::m=0;

void f(A *p) функции передается указатель на базовьт класс

{ (*Р)(). } вызов функции operatorO через указатель

void main(void)

{ А а1,а2,аЗ,а4;

f(&a3);

Результат: 4 A objects

А а5,а6;

f(&a6);

Результат: 6 A objects

В Ы,Ь2;

f{&b2);

Результат: 2 B objects

f(&a1);

Результат: 8 A objects

5.8. Функция operator->

Оператор -> определяется как унарный (однооперандный) оператор, записываемый в виде суффикса (т. е. после его операнда). Использование доопределенного оператора -> рассмотрим на следующем примере:

#include <iostream.h> class my class { int A;

public:

int B;

my class(int a,int b) : A(a), B(b) { } конструктор



int get A(void) { return A; }

class pointer {

my class* p;

public:

pointer(void) { p=new my class( 10,20); } конструктор ~pointer() ( delete p; } деструктор my class* operator->() { return p; };

void main(void)

{ pointer ptr; объявление объекта ptr класса pointer cout ptr->get A() endl; cout ptr->B endl; }

В этом примере доопределенный оператор -> используется для доступа к компонентам класса my class из объекта класса pointer примерно так же, как указатель на объект класса pointer имеет доступ к своим собственным компонентам. Действительно, ptr - это объект класса pointer, get A() и В - это компоненты класса my class. Доступ к этим компонентам осуществляется следующим образом: ptr->get AO и ptr->B. Выше говорилось, что -> рассматривается как унарный оператор, однако он не вводит новые синтаксические правила в язык С-ь-ь , поэтому следующее выражение является ошибочным: ptr-> (после знака -> надо записывать имя переменной или функции). Однако приведенные ниже выражения являются правильными:

cout ptr.operator->() endl;

cout (ptr.operator->())->B endl;

cout (*ptr.operator->()).B endl;

Результаты выполнения нашей программы представляются в виде:

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



как обычные объекты, когда осуществляется доступ к их собственным компонентам (см. прил. 2.2).

Для обычных указателей действия оператора -> можно выразить через операторы * и [ ], например, следующие выражения должны давать одинаковые результаты:

а -> Ь; здесь -> - это обычный оператор (*а).Ь; если а - указатель, то *а - объект а[0].Ь; если а - указатель, то а[0] - объект

Однако в общем случае для доопределенных операторов такая эквивалентность не может быть гарантирована. Этот вывод распространяется и на другие, доопределенные пользователем, операторы. Если необходимо, то требования эквивалентности указанных выше операторов можно описать явно, доопределив каждый из них соответствующим образом, например:

class my class {

another class* р; public:

another class* operator->() { return p; } another class& operator*() { return *p; } another class& operator[](int index) { return p[index]; }

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

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

#include <iostream.h> class Ptr {



1 ... 67 68 69 [ 70 ] 71 72 73 ... 159

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика