Динамическое выделение памяти для членов класса. Явные и неявные конструкторы копирования. Явные и неявные перегруженные операции присваивания. Что необходимо делать при использовании операции new в конструкторе. Использование статических членов класса. Использование указателей на объекты.
// string1.h — исправленное и расширенное объявление строкового класса
#ifndef STRING1_H_
#define STRING1_H_
#include <iostream>
using std::ostream;
using std::istream;
class String
{
private:
char * str; // указатель на строку
int len; // длина строки
static int num_strings; // количество объектов
static const int CINLIM = 80; // предел ввода для сіn
public:
// Конструкторы и другие методы
String(const char * s); // конструктор
String(); // конструктор по умолчанию
String(const String &); // конструктор копирования
~String();// деструктор
int length() const { return len; }
// Методы перегруженных операций
String & operator=(const String &);
String & operator=(const char *);
char & operator [] (int i);
const char & operator [] (int i) const;
// Дружественные функции перегруженных операций
friend bool operator<(const String &st, const String &st2);
friend bool operator>(const String &st1, const String &st2);
friend bool operator==(const String &st, const String &st2);
friend ostream & operator«(ostream & os, const String & st);
friend istream & operator» (istream & is, String & st);
// Статическая функция
static int HowMany();
};
#endif
// string1.срр — методы класса String
#include <cstring> // в некоторых случаях - string.h
#include "string1.h" // включение <iostream>
using std::cin;
using std::cout;
// Инициализация статического члена класса
int String::num_strings = 0;
// Статический метод
int String::HowMany()
{
return num_strings;
}
// Методы класса
String::String(const char * s) // создание String из С-строки
{
len = std::strlen(s); // установка размера
str = new char[len + 1]; // выделение памяти
std::strcpy(str, s); // инициализация указателя
num_strings++; // корректировка счетчика объектов
}
String::String()// конструктор по умолчанию
{
len = 4;
str = new char [1]
str[0] = '\0'; // строка по умолчанию
num_strings++;
}
String::String(const String & st) //конструктор копирования
{
num_strings++; // обработка обновления статического члена
len = st.len; // длина та же
str = new char [len + 1]; // выделение памяти
std::strcpy(str, st.str); // копирование строки в новое место
}
String::~String() // необходимый деструктор
{
--num_strings; // требуется
delete [] str; // требуется
}
// Методы перегруженных операций
// Присваивание объекта String объекту String
String & String::operator=(const String & st)
{
if (this == &st)
return *this;
delete [] str;
len = st.len;
str = new char [len + 1];
std::strcpy(str, st.str);
return *this;
}
// Присваивание С-строки объекту String
String & String::operator=(const char * s)
{
delete [] str;
len = std::strlen(s);
str = new char[len + 1];
std::strcpy(str, s);
return *this;
}
// Доступ для чтения и записи отдельных символов в неконстантном объекте String
char & String::operator [] (int i)
{
return str [i];
}
// Доступ только для чтения отдельных символов в константном объекте String
const char & String::operator [] (int i) const
{
return str [i];
}
// Дружественные функции перегруженных операций
bool operator<(const String &st1, const String &st2)
{
return (std::strcmp(st1.str, st2.str) < 0);
}
bool operator>(const String &st1, const String &st2)
{
return st2.str < st1.str;
}
bool operator==(const String &stl, const String &st2)
{
return (std::strcmp(st1.str, st2.str) == 0);
}
// Простой вывод String
ostream & operator«(ostream & os, const String & st)
{
os «st.str;
return os;
}
// Простой ввод String
istream & operator»(istream & is, String & st)
{
char temp[String::CINLIM];
is.get(temp, String::CINLIM);
if(is)
st = temp;
while(is && is.get()!= ' \n ')
continue;
return is;
}
// sayingsl.cpp — использование расширенного класса String
// компилировать вместе с string1.cpp
#include <iostream>
#include <cstdlib> // (или stdlib.h) для rand(), srand()
#include <ctime> // (или time.h) для time()
#include "string1.h"
const int ArSize = 10;
const int MaxLen =81;
int main()
{
using namespace std;
String name;
cout <<"Hi, what's your name?\n» "; // ввод имени
cin » name;
cout «name «", please enter up to " «ArSize «" short sayings <empty line to quit>:\n"; // ввод поговорки
String sayings[ArSize]; // массив объектов
char temp[MaxLen]; // временное хранилище для строки
int i;
for (i = 0; i < ArSize; i ++)
{
cout «i + 1 «": ";
cin.get(temp, MaxLen);
while (cin && cin.get()!= '\n')
continue;
if (!cin || temp[0] == '\0') // пустая строка?
break; // i не инкрементируется
else
sayings[i] = temp; // перегруженное присваивание
}
int total = i; // общее количество прочитанных строк
if (total > 0)
{
cout << "Here are your sayings:\n"; // вывод пословиц
for (i = 0; i < total; i + +)
cout << sayings [i] << "\n";
// Указатели для отслеживания кратчайшей и первой строки
String * shortest = &sayings[0]; // ицициализация первым объектом
String * first = &sayings[0];
for (i = 1; i < total; i++)
{
if (sayings[i].length () < shortest->length())
shortest = &sayings[i];
if (sayings [i] < *first) // сравнение значений
first = &sayings[i]; // присваивание адреса
}
cout «"Shortest saying: \n" << * shortest << endl; // вывод кратчайшей пословицы
cout «"First alphabetically: \n" «* first «endl; // вывод первой пословицы по алфавиту
srand(time (0));
int choice = rand() % total; // выбор случайного индекса
String * favorite = new String (sayings[choice]); // Создание и инициализация объекта String с помощью new
cout << "My favorite saying: \n" «*favorite << endl; // вывод любимой пословицы
delete favorite;
}
else
cout << "Not much to say, eh?\n"; // ничего не было введено
cout << "Bye. \n";
return 0;
}
Задание на дом
1. Имеется следующее объявление класса:
class Cow
{
char name[20];
char * hobby;
double weight;
public:
Cow();
Cow(const char * nm, const char * ho, double wt);
Cow(const Cow c &);
~Cow();
Cow & operator= (const Cow & c);
void ShowCow() const; // отображение всех данных Cow
};
Напишите реализацию для этого класса и короткую программу, использующую
все функции-члены.