This repository has been archived on 2023-05-13. You can view files and clone it, but cannot push or open issues or pull requests.
mipt_cpp/seminar02_encapsulation/classroom_tasks/code/2string/01constructor.cpp

166 lines
6.8 KiB
C++
Raw Normal View History

2022-09-14 19:05:27 +03:00
/*
Создадим строку, которая при создании (т.е в конструкторе) будет автоматически выделять необходимую память в Куче.
В чём-то реализация этой строки будет похожа на реализацию динамического массива из прошлого семестра.
У класса строки 3 поля:
mSize - размер - количество символов в строке (без учёта \0)
mCapacity - вместимость - количество выделенной памяти в Куче
mpData - указатель на выделенную память в Куче. В этой памяти строка будет иметь такой же вид, как и строка языка C.
В частности она будет иметь символ '\0' на конце.
Символ '\0' на конце оставим, чтобы было удобно конвертировать нашу строку в строку в стиле C.
Размер и вместимость это разные величины.
Например, для хранения строки "Cat" может быть выделено памяти под 10 символов, хоть и под эту строку было бы достаточно всего 4.
Представьте, что у вас есть длинная строка и вы хотите удалить последний символ в ней.
Если бы мы не хранили вместимость, а всегда выделяли памяти в притык, то в этом простом случае нам бы пришлось
перевыделять память и копировать всю строку в новую память.
Если же мы храним вместимость, то достаточно всего лишь уменьшить размер на 1 и поставит \0 в новый конец строки.
Теперь создадим конструктор, который будет выделять память и заполнять его нужным образом
Конструктор String(const char* str) конструирует нашу строку из строки в стиле C.
Принимаем на вход именно константную строку, так как в этом случае в конструктор можно будет
передать как константные, так и неконстантые строки.
Если бы мы написали так String(char* str) , то в конструктор нельзя было бы передать константные строки.
В строках:
size_t i = 0;
while (str[i] != '\0')
i++;
mSize = i;
mCapacity = i + 1;
мы находим размер переданной строки (strlen не используем, чтобы не связываться со старой библиотекой)
Вместимость на 1 больше, так как нужно учесть память под символ /0
В строке:
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
выделяем необходимую память
В строках:
for (size_t i = 0; str[i] != '\0'; i++)
mpData[i] = str[i];
mpData[mSize] = '\0';
копируем содержимое переданной строки в только что выделенную память.
Другие методы класса String:
getSize - возвращает размер строки
getCapacity - возвращает вместимость строки
cStr - возвращает строку в стиле C, то есть указатель на массив из char-ов с конечным символом \0
*/
#include <iostream>
#include <cstdlib>
using std::cout, std::endl, std::size_t;
class String
{
private:
size_t mSize;
size_t mCapacity;
char* mpData;
public:
String(const char* str)
{
size_t i = 0;
while (str[i] != '\0')
i++;
mSize = i;
mCapacity = i + 1;
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
for (size_t i = 0; str[i] != '\0'; i++)
mpData[i] = str[i];
mpData[mSize] = '\0';
}
size_t getSize() const
{
return mSize;
}
size_t getCapacity() const
{
return mCapacity;
}
const char* cStr() const
{
return mpData;
}
};
std::ostream& operator<<(std::ostream& out, const String& s)
{
out << s.cStr();
return out;
}
int main()
{
String a = "Cat";
String b = "Dog";
String c = "Lion";
cout << a << endl << b << endl << c << endl;
}
/*
Задание:
1) Создайте конструктор String(), который будет создавать пустую строку
(mSize = 0, mCapacity = 1, строка mpData содержит в себе 1 символ ('\0'))
Конструктор, который не принимает аргументов называется конструктором по умолчанию
2) Создайте конструктор String(size_t n, char a), который будет создавать строку из n символов a
(mSize = n, mCapacity = n + 1, строка mpData содержит в себе n + 1 символ (n раз a и '\0'))
2) Создайте конструктор String(const String& s), который будет создавать строку String из другой строки String
(mSize = s.mSize, mCapacity = s.mCapacity, строка mpData содержит в себе копию строки s.mpData)
Конструктор, который создаёт объект по другому объекту такого же типа называется конструктором копирования.
Протестируйте эти конструкторы:
String a;
cout << a << endl;
String b(10, 'q');
cout << b << endl;
String c("Cat");
cout << c << endl;
String d(c);
cout << d << endl;
*/