Перегрузка конструкторов и членов функций
Конструкторы и функции члены класса могут перегружаться, как обычные функции. В следующем примере продемонстрирован пример класса для хранения разнотипных значений (целых, вещественных и строковых). В качестве такого хранилища в классе в качестве члена данных используется анонимное объединение (union), позволяющее использовать для размещения разнотипных данных один и тот же участок памяти. Класс нашего примера содержит два закрытых члена данных (TypeVal- определяет тип хранимого значения и анонимное объединение для хранения самих значений), 4 перегруженных конструктора (обеспечивают инициализацию экземпляра класса значениями разных типов), 3 перегруженных варианта функции члена Set (с их помощью при работе с экземпляром в него можно записывать значения разных типов) и 3 функции для извлечения из экземпляра трех разных по типу значений.
Деструктор для этого класса не нужен, так как при уничтожении экземпляра никаких дополнительных операций не требуется.
const int SLen = 11; //Размер массива символов
const char Err [ ] = "\n*** Нет значения ***\n"; //Сообщение об ошибке
Class t_Variant
{
char TypeVal;// Тип значения (0 - нет значения; 1 - целое; 2 - вещественное; 3 - строка )
union {// Анонимное объединение для хранения значений разных типов
int IVal; //Целое значение
double DVal; //Вещественное значение
char SVal [ SLen ]; //Строка символов
};
public:
// Перегруженные конструкторы
t_Variant ( ) { TypeVal = 0; };// Нет значения
t_Variant ( int V ) { Set ( V ); }; //Инициализация целым
t_Variant ( double V ) { Set ( V ); }; //Инициализация вещественным
t_Variant ( char V [ ]) { Set ( V ); };// Инициализация строкой
// Перегруженные функции члены
void Set ( int V )// Присвоение целого значения
{ TypeVal = 1; IVal = V; }
void Set ( double V ) //Присвоение вещественного значения
{ TypeVal = 2; DVal = V; }
void Set ( char V[ ] ) //Присвоение строки
{ TypeVal = 3; strncpy_s( SVal, SLen, V, SLen – 1 ); }
// Остальные функции члены
int ToInt ( ) //Получение целого значения
{ if ( TypeVal == 1 ) return IVal; else {cout << Err; return 0;} }
double ToDouble ( ) //Получение вещественного значения
{ if ( TypeVal == 1 || TypeVal == 2 ) return DVal; else {cout << Err; return 0;} }
char * ToString ( )// Получение строки
{ if ( TypeVal == 3 ) return SVal; else {cout << Err; return "";} }
};
Посмотрим, как можно использовать этот класс.
Определим несколько экземпляров этого класса:
T_Variant V1;
При создании экземпляра V1будет использован вариант конструктора без параметров. В результате экземпляр V1 не содержит никаких данных, поэтому попытка получить из него какое-то значение приведет к выводу на экран сообщения об ошибке. Например:
cout << V1.ToDouble ();
На экране мы увидим сначала сообщение об ошибке *** Нет значения ***, а затем число 0, которое функция ToDouble возвращает при отсутствии в экземпляре конкретного значения запрошенного типа.
Пустой экземпляр V1 далее в программе с помощью одного из вариантов перегруженной функции Set можно заполнить какими-либо конкретными значениями:
V1.Set ( 3.14 );
После этого: cout << V1.ToDouble ();выведет на экран значение 3.14.
Этот же экземпляр далее в программе можно использовать для хранения и других типов значений:
V1.Set ( “Слово” );
cout << V1.ToString ();
На экране увидим: Слово.
При определении экземпляров этого класса их можно инициализировать конкретными значениями разных типов:
t_Variant V2 = 1001; //или так: t_Variant V2 ( 1001 );
t_Variant V3 = “Текст”; //или так: t_Variant V3 ( “Текст” );
Функциональность этого класса можно нарастить, приспособив его для хранения и других типов значений.
Замечание к примеру. В перегруженном варианте функции void Set ( char V[ ] ) использована функция strncpy_s, которая обеспечивает безопасное копирование одной строки символов в другой массив символов (разновидность функции strcpy). Прототип этой функции имеет 4 параметра и выглядит так:
void strncpy_s (char * Dest, int DestLen, char * Src, int TrancLen)
Функция копирует строку символов Srcв массив символов Dest.
DestLen –размер массива Dest.
TrancLen –количество символов, которое должно быть скопировано из Srcв Dest.
Иными словами, если длина строки Srcпревышает размер DestLen массива Dest, то из строки Srcв Destнадо скопировать TrancLenсимволов.
Дата добавления: 2019-02-07; просмотров: 253;