Сколько плюсов у C++? AvaLANche Xakep, номер #058, стр. 058-090-3 // файл "mystring.h" namespace MyString { // интерфейс bool assign (char*); // присвоение значения int length (); // возвращает длину строки char* value (); // возвращает значение } Получился довольно примитивный модуль :). Теперь посмотрим на его реализацию. // файл "mystring.с" #include <string.h> #include "mystring.h" namespace MyString { // реализация const int max_size = 1000; // максимальный размер int len = 0; // длина char v[max_size]; // массив символов } bool MyString::assign (char* str) { if (strlen (str) > max_size - 1) return false; if (!strcpy (v, str)) return false; else return true; } int MyString::length () { return len; } char* MyString::value () { return v; } Теперь пользователю достаточно заинклудить mystring.h, и можно пользоваться нашей строкой: // файл "user.c" #include "mystring.h" void f () { if (!MyString::assing ("Yo!")) cout << "Ошибка!"; else cout << MyString::value (); } Абстракция данных Используя модуль, описанный выше, ты в какой-то момент столкнешься с проблемой реализации нескольких таких строк. Действительно, трудно представить ситуацию, где достаточно одной подобной строки. Результатом долгих и тяжелых экспериментов над нашим модулем-строкой станет некое подобие типа данных, "псевдо тип" строка. Как это чудо сделать - описывать не буду, потому что такое решение проблемы далеко от идеала. На этот случай C++ припас свое решение - возможность определения типов, которые ведут себя почти как встроенные. Такие типы называются абстрактными или типами, определяемыми пользователем (пользовательскими). Просвещенные товарищи, знакомые с ООП, думаю, уже поняли, о чем речь. При работе с пользовательскими типами следует руководствоваться принципом "реши, какие потребуются типы, и обеспечь полный набор операций над ними". В контексте типа, определяемого пользователем, наша строка будет выглядеть примерно так: class MyString { int length; // длина char* v; // массив символов public: // создает строку из C-строки cstr MyString (char* cstr); // создает пустую строку по умолчанию - нулевой длины MyString (); MyString operator+ (MyString); // конкатенация bool operator== (MyString); // проверка на равенство // и так далее... }; Этот листинг демонстрирует объявление класса - пользовательского типа. Наш класс реализует строку и несколько операций над строками. По умолчанию все члены класса являются закрытыми (private), то есть доступ к ним имеют только функции-члены этого класса. Элементы, объявленные как "public", общедоступны. Сами функции-члены определяются примерно так: bool MyString::operator== (MyString mystr) { return (strcmp (v, mystr.v) == 0); } Функция-член, имеющая то же название, что и класс, называется конструктором. Конструкторы помогают по-разному инициализировать объекты класса - конкретные переменные. Обычно в них выделяется необходимая память, инициализируются переменные и т.п. В MyString, как видно из листинга, два конструктора: один по умолчанию, другой преобразует C-строку в "нашенскую". Пользоваться классом MyString можно так: |