|
Программирование >> Программирование на языке c++
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 через указатель
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 {
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |