Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Эта статья написана по материалам дискуссии в конференции RU.VISUAL.CPP сети FIDO. Основой примера шаблона свойства послужило письмо от "Vyacheslav V. Lanovets" от 6 декабря 2000г.

Развитие современных систем программирования в направлении объектно-ориентированного и компонентно-ориентированного, а также визуального программирования привело к тому, что многие распространённые и хорошо известные алгоритмические языки перестали соответствовать потребностям современного рынка средств разработки. Одним из таких "нововведений" стали свойства объекта. В общем случае, свойство это пара функций, одна из которых отвечает за установку некоторого значения, а другая за его считывание. Такое решение позволяет, во-первых, обеспечить инкапсуляцию данных и защиту их от неправомерного доступа, а во-вторых, обеспечить целостность данных. Необходимость использования свойств возникает тогда, когда при изменении некоторого параметра требуется произвести ещё некоторые действия.

В тех языках программирования, синтаксис которых находится под контролем создателей (таких как "Visual Basic" или "Delphi") концепция свойств реализована на уровне синтаксиса. В частности, обращение к свойствам объекта производится оператором присваивания, как при обращении к переменной-члену класса в C++. Однако, не стоит обольщаться по поводу простоты синтаксиса. Не стоит забывать, что в простейшем выражении типа

theObject.theProperty = theValue

производится неявный вызов функции.

К сожалению, строгий и стандартизированный язык C++ не позволяет добавлять в его синтаксис столь революционные новации. Какие же возможности предоставляет разработчику C++?

Наиболее простой и самый распространённый способ обеспечения инкапсуляции в C++ заключается в написании пары функций типа get_Value и put_Value для каждого параметра. Заметим, что именно так реализованы свойства в технологии Automation. При использовании этого способа можно написать примерно такой класс:

class CValue {

private:

 int m_value;

public:

 int get_Value {

return m_value; // Или более сложная логика

 }

 void put_Value(int value) {

m_value = value; // Или более сложная логика

 }

};

В этом случае для обращения к такому "свойству" программист должен написать вызов соответствующей функции.

Хорошо это или плохо, но современные средства разработки "приучили" многих к использованию свойств в операторах присваивания и вообще обращению с ними, как с переменными-членами. Учитывая это, разработчики Microsoft Visual C++ добавили в синтаксис языка несколько "Microsoft Specific" конструкций. В частности, модификатор __declspec получил дополнительный параметр "property". Теперь в классе можно объявить "виртуальную" переменную и связать её с соответствующими функциями. Теперь класс может выглядеть примерно так:

class CValue {

private:

 int m_value;

public:

 __declspec(property(get=get_Value, put=put_Value)) int Value;

 int get_Value {

return m_value; // Или более сложная логика

 }

 void put_Value(int value){

m_value = value; // Или более сложная логика

 }

};

Строчка сразу за "public:" объявляет "виртуальную" переменную типа int, при обращении к которой фактически будут вызваться функции. С этим классом можно будет работать примерно так:

CValue val; val.Value = 50; // На самом деле вызов put_Value

int z = val.Value; // На самом деле вызов get_Value

Чем не "настоящие" свойства? Однако следует заметить, что модификатор __declspec(property) был введён не для повседневного использования, а для встроенной в компилятор поддержки технологии COM. Дело в том, что директива импорта библиотеки типа (что бы знать, что это такое, читайте книжки по COM) #import заставляет компилятор VC автоматически генерировать вспомогательные классы-обёртки для объектов COM. Вот в этих "автоматических" классах модификатор __declspec(property) используется достаточно широко для максимальной приближенности к синтаксису Visual Basic'а. Приближенность к синтаксису VB достигает такой степени, что свойства сделаны индексными. Для этого, достаточно поставить квадратные скобки после объявления "виртуальной переменной":

__declspec(property(get=get_Value, put=put_Value)) int Value[]; 

После такого объявления свойство "Value" может принимать один или несколько параметров-индексов, передаваемых в квадратных скобках. Так, например, вызов

Val.Value[f]["two"] = 10;

Будет преобразован в вызов функции

Val.put_Value(f, "two", 10);

Главным недостатком описанного выше способа использования свойств в C++ является его зависимость от компилятора, пресловутая "Microsoft Specific". Впрочем, другой, не менее известный компилятор "Borland C++ Builder" реализует концепцию свойств далёким от стандарта способом. В любом случае часто требуется (или хочется) достичь независимости от компилятора и соответствия кода программы стандарту C++. Что же делать? Оказывается язык C++ позволяет реализовать концепцию свойств в стиле Visual Basic'а. Для этого необходимо воспользоваться шаблонами и перекрыть операторы присваивания и приведения типа. Но для начала необходимо провести некоторую подготовительную работу:

// Базовый класс шаблона свойства.

template <typename proptype, typename propowner> class property {

protected:

 typedef proptype (propowner::*getter);

 typedef void (propowner::*setter)(proptype);

 propowner *m_owner;

 getter m_getter;

 setter m_setter;

public:

 // Оператор приведения типа. Реализует свойство для чтения.

  • Читать дальше
  • 1
  • ...
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: