seminar2
This commit is contained in:
parent
46d1c64684
commit
ab6732eded
98 changed files with 10319 additions and 0 deletions
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Раздельная компиляция.
|
||||
|
||||
В этой части мы вынесем весь код, связанный с нашим классом Point в отдельные файлы.
|
||||
А также скомпилируем отдельно код, относящийся к нашему классу Point.
|
||||
|
||||
Это будет проделано в следующий примерах, а пока тут просто лежит код
|
||||
класса Point из предыдущих частей.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
using std::cout, std::endl;
|
||||
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Вынос определений методов вне класса.
|
||||
|
||||
Методы внутри класса можно только объявить, а определить их можно вне класса.
|
||||
Например, метод norm объявлен внутри класса:
|
||||
|
||||
float norm() const;
|
||||
|
||||
а определён вне класса:
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
|
||||
Чтобы компилятор понимал к какому классу относится тот или иной метод,
|
||||
к его имени вне класса нужно добавить название класса и два двоеточия.
|
||||
Поэтому метод norm вне класса Point называется как Point::norm.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
using std::cout, std::endl;
|
||||
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const;
|
||||
float norm() const;
|
||||
Point operator*(float k) const;
|
||||
void normalize();
|
||||
};
|
||||
|
||||
|
||||
Point Point::operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point Point::operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Перенос кода в заголовочный файл
|
||||
|
||||
В этом примере мы перенесли весь код, связанный с классом Point в отдельный файл point.hpp.
|
||||
Файл point.hpp подключается к файлу main.cpp с помощью директивы #include в строке:
|
||||
|
||||
#include "point.hpp"
|
||||
|
||||
На самом деле директива #include делает очень простую вещь: она просто берёт всё содержимое
|
||||
передаваемого ей файла и вставляет это содержимое на место директивы.
|
||||
То есть в этом примере за место #include "point.hpp" подставится всё содержимое файла point.hpp.
|
||||
|
||||
Так как директива #include уже сама вставила файл point.hpp в файл main.cpp, то дополнительно
|
||||
указывать файл point.hpp при компиляции не нужно. Скомпилировать этот пример можно так:
|
||||
|
||||
g++ main.cpp
|
||||
|
||||
|
||||
Стандартные библиотеки типа iostream подключаются так же. То есть где-то в системе, в какой-то папке
|
||||
хранится стандартная библиотека C++ и, соответственно, есть файл под название iostream (без расширения).
|
||||
Этот файл и подставляется за место строки #include <iostream>.
|
||||
Чтобы посмотреть в каких папках компилятор ищет файлы стандартной библиотеки можно скомпилировать программу так:
|
||||
|
||||
g++ -v main.cpp
|
||||
|
||||
Он напечатает множество информации о компиляции, в числе прочего пути где происходит поиск при исполнении #include.
|
||||
Вы могли заметить, что стандартные библиотеки в директиве #include пишутся в треугольных скобочках, а нашу
|
||||
библиотеку point.hpp мы написали в двойных кавычках. В чём разница между этими вариантами?
|
||||
На самом деле разница лишь в том, в каких папках компилятор ищет данные файлы.
|
||||
Если мы пишем библиотеку в треугольных скобках, то компилятор ищет её в папках стандартной библиотеки.
|
||||
Если мы пишем библиотеку в кавычках, то компилятор ищет её в папках текущей директории.
|
||||
|
||||
|
||||
|
||||
Защита от двойного включения
|
||||
|
||||
Используя директивы #include, очень легко включить один и тот же файл 2 и более раз.
|
||||
Например, в этом примере файл iostream включается 2 раза: один раз непосредственно в файле main.cpp, а второй раз
|
||||
он включится после того, как включиться файл point.hpp. Внутри файла point.hpp тоже есть #include <iostream>.
|
||||
Если не предпринимать никаких действий, то произойдёт ошибка, так как одинаковые функции и классы
|
||||
будут повторяться в программе несколько раз.
|
||||
|
||||
Чтобы защититься от этой проблемы нужно в начале заголовочного файла написать директиву
|
||||
|
||||
#pragma once
|
||||
|
||||
Таким образом компилятор будет понимать, что вы не хотите включать файл более одного раза и включит только одну копию файла.
|
||||
Эта директива была использовани и в файле point.hpp.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "point.hpp"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Всё что относится к классу Point мы перенесли в отдельный файл point.hpp.
|
||||
А также мы разделили объявления и определения методов в файле point.hpp.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "point.hpp"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const;
|
||||
float norm() const;
|
||||
Point operator*(float k) const;
|
||||
void normalize();
|
||||
};
|
||||
|
||||
|
||||
Point Point::operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point Point::operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Раздельная компиляция
|
||||
|
||||
Теперь мы разделим объявления и определения всех методов класса Point.
|
||||
Все объявления класса Point поместим в файл point.hpp, а определения методов в файл point.cpp.
|
||||
Таким образом у нас получилось 2 компилируемых файла: main.cpp и point.cpp и 1 заголовочный файл point.hpp.
|
||||
|
||||
При этом заголовочный файл point.hpp должен подключаться везде, где используется класс Point.
|
||||
То есть в данном случае он должен подключаться и в файл main.cpp и в файл point.cpp.
|
||||
|
||||
|
||||
Для компиляции программы нужно указать компилятору на все компилируемые файлы вот так:
|
||||
|
||||
g++ main.cpp point.cpp
|
||||
|
||||
Если это не сделать и скомпилировать только файл main.cpp, то возникнет ошибка undefined reference to norm().
|
||||
Грубо говоря программа будет знать, что есть класс Point и знать его методы (так как это всё описано в point.hpp),
|
||||
но любые попытки вызвать эти методы будут приводить к ошибке, так как они не были скомпилированы.
|
||||
|
||||
|
||||
Преемущество раздельной компиляции заключается в том, что компилировать разные .cpp файлы можно поотдельности.
|
||||
Представьте, что у вас огромный проект, содержащий тысячи файлов и миллионы строк кода. Такой проект может компилироваться часами.
|
||||
Теперь вы сделали небольшое изменение в одном файле этого проекта. Если бы нельзя было бы компилировать файлы поотдельности,
|
||||
то после любого изменения вам бы пришлось компилировать весь проект заново и ждать часы пока компиляция закончится.
|
||||
К счастью, .cpp файлы можно компилировать поотдельности и, если вы сделали изменение в одном файле, то скомпилировать
|
||||
потребуется только тот файл, который вы изменили.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "point.hpp"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "point.hpp"
|
||||
|
||||
Point Point::operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point Point::operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const;
|
||||
float norm() const;
|
||||
Point operator*(float k) const;
|
||||
void normalize();
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a);
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Пространства имён
|
||||
|
||||
|
||||
Имя Point достаточно распространённое и есть очень большая вероятность того, что при подключении нескольких библиотек
|
||||
в некоторых из них тоже будет класс с именем Point. Конечно, если ничего не предпринять, это приведёт к ошибке.
|
||||
|
||||
Чтобы избежать ошибок, связанных с конфликтами имён, положим весь код нашего класса Point в пространство имён mipt.
|
||||
Для этого обернём наш код в файлах point.hpp и point.cpp
|
||||
|
||||
namespace mipt
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
Теперь наш класс Point будет лежать в пространстве имён mipt.
|
||||
Для его использования вне пространства имён mipt нужно писать mipt::Point (ну либо использовать using mipt::Point;)
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include "point.hpp"
|
||||
|
||||
using std::cout, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
mipt::Point a = {7.2, 3.1};
|
||||
cout << a.norm() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include "point.hpp"
|
||||
|
||||
namespace mipt
|
||||
{
|
||||
|
||||
Point Point::operator+(Point b) const
|
||||
{
|
||||
Point result = {x + b.x, y + b.y};
|
||||
return result;
|
||||
}
|
||||
|
||||
float Point::norm() const
|
||||
{
|
||||
return std::sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
Point Point::operator*(float k) const
|
||||
{
|
||||
Point result = {k * x, k * y};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Point::normalize()
|
||||
{
|
||||
float normv = norm();
|
||||
x /= normv;
|
||||
y /= normv;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a)
|
||||
{
|
||||
out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace mipt
|
||||
{
|
||||
|
||||
struct Point
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Point operator+(Point b) const;
|
||||
float norm() const;
|
||||
Point operator*(float k) const;
|
||||
void normalize();
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Point a);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
В данной программе содержится класс String, написанный нами в одной из предыдущих частей.
|
||||
|
||||
Задачи:
|
||||
|
||||
1) Вынесите класс String в отдельный заголовочный файл string.hpp и скомпилируйте программу.
|
||||
|
||||
|
||||
2) Вынесите объявления методов класса String в заголовочный файл string.hpp, а определения
|
||||
методов в компилируемый файл string.cpp. Скомпилируйте программу.
|
||||
|
||||
|
||||
3) Вынесите объявления методов класса String в заголовочный файл string.hpp, а определения
|
||||
методов в компилируемый файл string.cpp. А также поместите весь код класса String в пространство имён mipt.
|
||||
Скомпилируйте программу.
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
|
||||
std::size_t mSize;
|
||||
std::size_t mCapacity;
|
||||
char* mpData;
|
||||
|
||||
public:
|
||||
|
||||
String(const char* str)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (str[i] != '\0')
|
||||
i++;
|
||||
mSize = i;
|
||||
mCapacity = i + 1;
|
||||
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; str[i]; i++)
|
||||
mpData[i] = str[i];
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String() : String("") {}
|
||||
String(const String& s) : String(s.cStr()) {}
|
||||
|
||||
String(std::size_t n, char a)
|
||||
{
|
||||
mSize = n;
|
||||
mCapacity = n + 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
std::free(mpData);
|
||||
}
|
||||
|
||||
void reserve(std::size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = capacity;
|
||||
char* newData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
newData[i] = mpData[i];
|
||||
newData[mSize] = '\0';
|
||||
|
||||
std::free(mpData);
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void resize(std::size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
for (std::size_t i = 0; i <= mSize; ++i)
|
||||
mpData[i] = right.mpData[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
result.mpData[i] = mpData[i];
|
||||
|
||||
for (std::size_t i = 0; i < b.mSize; ++i)
|
||||
result.mpData[mSize + i] = b.mpData[i];
|
||||
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool operator<(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator<=(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& operator[](std::size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& at(std::size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
std::cout << "Error! Index is out of bounds." << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
std::free(mpData);
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
std::size_t getSize() const {return mSize;}
|
||||
std::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;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (x == ' ' || x == '\n' || x == '\t')
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
String a = "Mouse";
|
||||
String b;
|
||||
std::cin >> b;
|
||||
String c = b;
|
||||
|
||||
if (a + c == "MouseLion")
|
||||
std::cout << "Yes" << std::endl;
|
||||
else
|
||||
std::cout << "No" << std::endl;
|
||||
|
||||
|
||||
if (a > "Mice")
|
||||
std::cout << "Yes" << std::endl;
|
||||
else
|
||||
std::cout << "No" << std::endl;
|
||||
|
||||
|
||||
c[0] = 'P';
|
||||
std::cout << c << std::endl;
|
||||
|
||||
c += a;
|
||||
std::cout << c << std::endl;
|
||||
|
||||
c = c + String(10, 'q');
|
||||
std::cout << c << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include "string.hpp"
|
||||
|
||||
using std::cout, std::cin, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
String a = "Mouse";
|
||||
String b;
|
||||
cin >> b;
|
||||
String c = b;
|
||||
|
||||
if (a + c == "MouseLion")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
if (a > "Mice")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
c[0] = 'P';
|
||||
cout << c << endl;
|
||||
|
||||
c += a;
|
||||
cout << c << endl;
|
||||
|
||||
c = c + String(10, 'q');
|
||||
cout << c << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
|
||||
std::size_t mSize;
|
||||
std::size_t mCapacity;
|
||||
char* mpData;
|
||||
|
||||
public:
|
||||
|
||||
String(const char* str)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (str[i] != '\0')
|
||||
i++;
|
||||
mSize = i;
|
||||
mCapacity = i + 1;
|
||||
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; str[i]; i++)
|
||||
mpData[i] = str[i];
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String() : String("") {}
|
||||
String(const String& s) : String(s.cStr()) {}
|
||||
|
||||
String(std::size_t n, char a)
|
||||
{
|
||||
mSize = n;
|
||||
mCapacity = n + 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
std::free(mpData);
|
||||
}
|
||||
|
||||
void reserve(std::size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = capacity;
|
||||
char* newData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
newData[i] = mpData[i];
|
||||
newData[mSize] = '\0';
|
||||
|
||||
std::free(mpData);
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void resize(std::size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
for (std::size_t i = 0; i <= mSize; ++i)
|
||||
mpData[i] = right.mpData[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
result.mpData[i] = mpData[i];
|
||||
|
||||
for (std::size_t i = 0; i < b.mSize; ++i)
|
||||
result.mpData[mSize + i] = b.mpData[i];
|
||||
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool operator<(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator<=(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& operator[](std::size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& at(std::size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
std::cout << "Error! Index is out of bounds." << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
std::free(mpData);
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
std::size_t getSize() const {return mSize;}
|
||||
std::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;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (x == ' ' || x == '\n' || x == '\t')
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
Компиляция:
|
||||
|
||||
g++ main.cpp string.cpp
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "string.hpp"
|
||||
using std::cout, std::cin, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
String a = "Mouse";
|
||||
String b;
|
||||
cin >> b;
|
||||
String c = b;
|
||||
|
||||
if (a + c == "MouseLion")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
if (a > "Mice")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
c[0] = 'P';
|
||||
cout << c << endl;
|
||||
|
||||
c += a;
|
||||
cout << c << endl;
|
||||
|
||||
c = c + String(10, 'q');
|
||||
cout << c << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include "string.hpp"
|
||||
|
||||
|
||||
String::String(const char* str)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (str[i] != '\0')
|
||||
i++;
|
||||
mSize = i;
|
||||
mCapacity = i + 1;
|
||||
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; str[i]; i++)
|
||||
mpData[i] = str[i];
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String::String() : String("") {}
|
||||
String::String(const String& s) : String(s.cStr()) {}
|
||||
|
||||
String::String(std::size_t n, char a)
|
||||
{
|
||||
mSize = n;
|
||||
mCapacity = n + 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
std::free(mpData);
|
||||
}
|
||||
|
||||
void String::reserve(std::size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = capacity;
|
||||
char* newData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
newData[i] = mpData[i];
|
||||
newData[mSize] = '\0';
|
||||
|
||||
std::free(mpData);
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void String::resize(std::size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& String::operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
for (std::size_t i = 0; i <= mSize; ++i)
|
||||
mpData[i] = right.mpData[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String String::operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
result.mpData[i] = mpData[i];
|
||||
|
||||
for (std::size_t i = 0; i < b.mSize; ++i)
|
||||
result.mpData[mSize + i] = b.mpData[i];
|
||||
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& String::operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool String::operator<(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator<=(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool String::operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool String::operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& String::operator[](std::size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& String::at(std::size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
std::cout << "Error! Index is out of bounds." << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void String::clear()
|
||||
{
|
||||
std::free(mpData);
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void String::addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
std::size_t String::getSize() const {return mSize;}
|
||||
std::size_t String::getCapacity() const {return mCapacity;}
|
||||
const char* String::cStr() const {return mpData;}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s)
|
||||
{
|
||||
out << s.cStr();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (x == ' ' || x == '\n' || x == '\t')
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
|
||||
std::size_t mSize;
|
||||
std::size_t mCapacity;
|
||||
char* mpData;
|
||||
|
||||
public:
|
||||
|
||||
String(const char* str);
|
||||
|
||||
String();
|
||||
String(const String& s);
|
||||
|
||||
String(std::size_t n, char a);
|
||||
~String();
|
||||
|
||||
void reserve(std::size_t capacity);
|
||||
void resize(std::size_t size);
|
||||
|
||||
String& operator=(const String& right);
|
||||
String operator+(const String& b);
|
||||
String& operator+=(const String& right);
|
||||
|
||||
bool operator==(const String& right) const;
|
||||
bool operator<(const String& right) const;
|
||||
bool operator<=(const String& right) const;
|
||||
bool operator!=(const String& right) const;
|
||||
bool operator>(const String& right) const;
|
||||
bool operator>=(const String& right) const;
|
||||
|
||||
char& operator[](std::size_t i);
|
||||
char& at(std::size_t i);
|
||||
|
||||
void clear();
|
||||
void addCharacter(char c);
|
||||
|
||||
std::size_t getSize() const;
|
||||
std::size_t getCapacity() const;
|
||||
const char* cStr() const;
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s);
|
||||
std::istream& operator>>(std::istream& in, String& s);
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#include <iostream>
|
||||
#include "string.hpp"
|
||||
using std::cout, std::cin, std::endl;
|
||||
|
||||
int main()
|
||||
{
|
||||
mipt::String a = "Mouse";
|
||||
mipt::String b;
|
||||
cin >> b;
|
||||
mipt::String c = b;
|
||||
|
||||
if (a + c == "MouseLion")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
if (a > "Mice")
|
||||
cout << "Yes" << endl;
|
||||
else
|
||||
cout << "No" << endl;
|
||||
|
||||
|
||||
c[0] = 'P';
|
||||
cout << c << endl;
|
||||
|
||||
c += a;
|
||||
cout << c << endl;
|
||||
|
||||
c = c + mipt::String(10, 'q');
|
||||
cout << c << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include "string.hpp"
|
||||
|
||||
namespace mipt {
|
||||
|
||||
String::String(const char* str)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (str[i] != '\0')
|
||||
i++;
|
||||
mSize = i;
|
||||
mCapacity = i + 1;
|
||||
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; str[i]; i++)
|
||||
mpData[i] = str[i];
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String::String() : String("") {}
|
||||
String::String(const String& s) : String(s.cStr()) {}
|
||||
|
||||
String::String(std::size_t n, char a)
|
||||
{
|
||||
mSize = n;
|
||||
mCapacity = n + 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
mpData[i] = a;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
std::free(mpData);
|
||||
}
|
||||
|
||||
void String::reserve(std::size_t capacity)
|
||||
{
|
||||
if (capacity <= mCapacity)
|
||||
return;
|
||||
|
||||
mCapacity = capacity;
|
||||
char* newData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
newData[i] = mpData[i];
|
||||
newData[mSize] = '\0';
|
||||
|
||||
std::free(mpData);
|
||||
mpData = newData;
|
||||
}
|
||||
|
||||
|
||||
void String::resize(std::size_t size)
|
||||
{
|
||||
reserve(size + 1);
|
||||
mSize = size;
|
||||
mpData[mSize] = '\0';
|
||||
}
|
||||
|
||||
|
||||
String& String::operator=(const String& right)
|
||||
{
|
||||
if (this == &right)
|
||||
return *this;
|
||||
|
||||
mSize = right.mSize;
|
||||
resize(mSize);
|
||||
|
||||
for (std::size_t i = 0; i <= mSize; ++i)
|
||||
mpData[i] = right.mpData[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
String String::operator+(const String& b)
|
||||
{
|
||||
String result;
|
||||
result.resize(mSize + b.mSize);
|
||||
|
||||
for (std::size_t i = 0; i < mSize; ++i)
|
||||
result.mpData[i] = mpData[i];
|
||||
|
||||
for (std::size_t i = 0; i < b.mSize; ++i)
|
||||
result.mpData[mSize + i] = b.mpData[i];
|
||||
|
||||
result.mpData[result.mSize] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String& String::operator+=(const String& right)
|
||||
{
|
||||
*this = *this + right;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator==(const String& right) const
|
||||
{
|
||||
if (mSize != right.mSize)
|
||||
return false;
|
||||
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return i == mSize;
|
||||
}
|
||||
|
||||
bool String::operator<(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] < right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator<=(const String& right) const
|
||||
{
|
||||
std::size_t i = 0;
|
||||
while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i])
|
||||
i++;
|
||||
|
||||
return mpData[i] <= right.mpData[i];
|
||||
}
|
||||
|
||||
bool String::operator!=(const String& right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
|
||||
bool String::operator>(const String& right) const
|
||||
{
|
||||
return !(*this <= right);
|
||||
}
|
||||
|
||||
bool String::operator>=(const String& right) const
|
||||
{
|
||||
return !(*this < right);
|
||||
}
|
||||
|
||||
char& String::operator[](std::size_t i)
|
||||
{
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
char& String::at(std::size_t i)
|
||||
{
|
||||
if (i >= mSize)
|
||||
{
|
||||
std::cout << "Error! Index is out of bounds." << std::endl;
|
||||
std::exit(1);
|
||||
}
|
||||
return mpData[i];
|
||||
}
|
||||
|
||||
void String::clear()
|
||||
{
|
||||
std::free(mpData);
|
||||
|
||||
mSize = 0;
|
||||
mCapacity = 1;
|
||||
mpData = (char*)std::malloc(sizeof(char) * mCapacity);
|
||||
mpData[0] = '\0';
|
||||
}
|
||||
|
||||
void String::addCharacter(char c)
|
||||
{
|
||||
if (mSize + 1 == mCapacity)
|
||||
reserve(2 * mCapacity);
|
||||
|
||||
mpData[mSize] = c;
|
||||
resize(mSize + 1);
|
||||
}
|
||||
|
||||
|
||||
std::size_t String::getSize() const {return mSize;}
|
||||
std::size_t String::getCapacity() const {return mCapacity;}
|
||||
const char* String::cStr() const {return mpData;}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s)
|
||||
{
|
||||
out << s.cStr();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& in, String& s)
|
||||
{
|
||||
s.clear();
|
||||
while (true)
|
||||
{
|
||||
char x = in.get();
|
||||
if (x == ' ' || x == '\n' || x == '\t')
|
||||
break;
|
||||
s.addCharacter(x);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace mipt {
|
||||
|
||||
class String
|
||||
{
|
||||
private:
|
||||
|
||||
std::size_t mSize;
|
||||
std::size_t mCapacity;
|
||||
char* mpData;
|
||||
|
||||
public:
|
||||
|
||||
String(const char* str);
|
||||
|
||||
String();
|
||||
String(const String& s);
|
||||
|
||||
String(std::size_t n, char a);
|
||||
~String();
|
||||
|
||||
void reserve(std::size_t capacity);
|
||||
void resize(std::size_t size);
|
||||
|
||||
String& operator=(const String& right);
|
||||
String operator+(const String& b);
|
||||
String& operator+=(const String& right);
|
||||
|
||||
bool operator==(const String& right) const;
|
||||
bool operator<(const String& right) const;
|
||||
bool operator<=(const String& right) const;
|
||||
bool operator!=(const String& right) const;
|
||||
bool operator>(const String& right) const;
|
||||
bool operator>=(const String& right) const;
|
||||
|
||||
char& operator[](std::size_t i);
|
||||
char& at(std::size_t i);
|
||||
|
||||
void clear();
|
||||
void addCharacter(char c);
|
||||
|
||||
std::size_t getSize() const;
|
||||
std::size_t getCapacity() const;
|
||||
const char* cStr() const;
|
||||
};
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, const String& s);
|
||||
std::istream& operator>>(std::istream& in, String& s);
|
||||
|
||||
}
|
||||
Reference in a new issue