CodeRules_M102
.pdf
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 1 из 23  | 
Правила кодирования
неООП (часть 1)
Введение
Область действия правил ограничена курсом.
Любая система лучше, чем бессистемное и разнородное.
Общие принципы
1. Каждое нарушение правила должно быть аргументировано и задокументировано.
Исходные тексты
2.Запрещается использовать спецсимволы (табуляции, разрыв страницы) в исходных текстах.
3.Длина строки исходного файла ограничена 80 символами. Используйте разрывы строк для
более длинных строк.
Основание: реализация ограничения на длину строки происходит либо отбрасывание, либо переносом конца, при этом исходный текст становится трудным для восприятия. Отсутствие ограничения на длину строки у других разработчиков гарантировать невозможно. 80 является общепризнанным соглашением о количестве символов в строке редакторов, эмуляторов терминалов (консолей), принтеров и отладчиков.
4.Делайте очевидным и хорошо заметным в коде разрыв строки. Выравнивайте новую строку в соответствии с предыдущей строкой.
ПРИМЕР
totalSum = a + b + c + d + e;
function (param1, param2, param3);
setText ("Long line split" "into two parts.");
for (int tableNo(0); tableNo < nTables; tableNo += tableStep)
{
}
unsigned char searchTable[] = { 0x00, 0x01, 0x01, 0x02, 0x01, 0x1, 0x02, 0x01, 0x02, 0x03, 0x01, 0x01, 0x02, 0x1, 0x02, 0x03}
5.Используйте для путей (имен папок, имен и расширений файлов) в дереве исходных текстов символы только нижнего регистра.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
creportgenerator.h  | 
	CReportGenerator.h  | 
  | 
	
  | 
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 2 из 23  | 
6.Используйте для различных типов файлов следующие расширения:
●«h» - заголовочные файлы С++
●«cpp» - файлы реализаций С++
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
creportgenerator.h  | 
	crepgen.H  | 
creportgenerator.cpp  | 
	crepgen.hpp  | 
  | 
	report_generator.cxx  | 
  | 
	report.c  | 
  | 
	
  | 
7. Все определения размещайте в файлах реализации. Естественным исключением являются шаблонные (template) и встраиваемые (inline) функции и классы, для которых определение размещается в том же в заголовочном файле что и объявление, но отдельно от последнего.
Основание: заголовочный файл должен предоставлять интерфейс, а реализация такого интерфейса должна быть размещена в в файле реализации.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
// In median.h  | 
	// In median.h  | 
  | 
	int findMedian(int* pData, int cnt)  | 
int findMedian(int* pData, int cnt);  | 
	{  | 
  | 
	"statements";  | 
// In median.cpp  | 
	}  | 
int findMedian(int* pData, int cnt)  | 
	
  | 
{  | 
	
  | 
"statements";  | 
	
  | 
}  | 
	
  | 
  | 
	
  | 
Использование заголовочные файлов
8.Включения всех заголовочных файлов размещайте в начале файла.
9.В каждый заголовочный файл встраивайте механизм защиты от повторного включения ("стражи включения"). Запрещено использовать нестандартные расширения языка для предотвращения повторного включения заголовков. Не рекомендуется использовать UID, GUID
и т.д.
Рекомендуемая схема состоит в использовании определения макроса, имя которого составляется из имени файла, расширения и даты создания файла (для большей уникальности в составе больших проектов).
ПРАВИЛЬНО
#ifndef HEADERNAME_H_20070521 #define HEADERNAME_H_20070521
...
#endif // ifndef HEADERNAME_H_20070521
НЕПРАВИЛЬНО
CTABLE_H__3FF90365_AEBE_4F17_ABB0_93D70BABB93F__INCLUDED_ // плохо читается
#pragma once; // нестандартное расширение языка С++
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 3 из 23  | 
10.Используйте только относительный пути для включаемых заголовочных файлов. Используйте символ слеш ('/') при указании пути (к файлу). Для указания папок поиска заголовочных файлов используйте опции компилятора (настройки проектов в среде разработки) и системные настройки.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
#include "h/intr/propertiesdialog.h" #include "c:/prj/h/itr/PropDlg.h"
11.Упорядочивайте и группируйте включения заголовочных фалов. Для группировки используйте пустые строки между группами. Заголовки включайте в порядке увеличения общности, то есть сначала включайте более частные заголовочные файлы, а затем — более общие. Такой порядок соответствует следующему порядку:
●пользовательские заголовки;
●заголовки общего пользования;
●заголовки стандартной библиотеки.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
#include "propertiesdialog.h"  | 
	#include <iosfwd>  | 
#include "mainwindow.h"  | 
	#include <iomanip>  | 
  | 
	#include <qt/QTextField.h>  | 
#include <qt/QButton.h>  | 
	#include <qt/QButton.h>  | 
#include <qt/QTextField.h>  | 
	#include "mainwindow.h"  | 
  | 
	#include "propertiesdialog.h"  | 
#include <iomanip>  | 
	
  | 
#include <iosfwd>  | 
	
  | 
  | 
	
  | 
12.Заголовочный файл должен включать только те заголовочные файлы, которые требуются для компиляции. Если включение некоторого заголовка требуется в cpp-файле, то включение должно быть в последнем, а не в соответствующем этому cpp заголовке.
Использование препроцессора
13.Минимизируйте использования препроцессора. Используйте только следующие директивы препроцессора:
●#ifndef
●#define
●#endif
●#include
14.Избегайте использования препроцессора для определения константных значений. Вместо препроцессора используйте константы, перечисления и статические методы классов.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
const int PAGE_A4_WIDTH_PX(2400);  | 
	#define PAGE_A4_WIDTH_PX_WIDTH_PX 2400  | 
  | 
	
  | 
class CPageGeomtryStandart  | 
	
  | 
{  | 
	
  | 
public:  | 
	
  | 
static int getPageA4Width();  | 
	
  | 
};  | 
	
  | 
  | 
	
  | 
enum RgbColor  | 
	#define COLOR_RED 0xff0000  | 
{  | 
	#define COLOR_BLUE 0x0000ff  | 
RED = 0xff0000,  | 
	#define COLOR_GREN 0x00ff00  | 
BLUE = 0x0000ff,  | 
	
  | 
GREN = 0x00ff00  | 
	
  | 
};  | 
	
  | 
  | 
	
  | 
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.) 05.02.10 стр. 4 из 23
15.Избегайте использования препроцессора для определения подставляемого в виде макросов фрагментов исходного кода. Вместо препроцессора используйте шаблонные и встраиваемые
(inline) функции.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
template<class T>  | 
	#define min(a,b) (((a) < (b)) ?\  | 
T  | 
	(a) : (b));  | 
min(const T& lhs, const T& rhs)  | 
	
  | 
{  | 
	
  | 
return (lhs < rhs) ? lhs : rhs;  | 
	
  | 
}  | 
	
  | 
  | 
	
  | 
inline int min(int lhs, int rhs)  | 
	
  | 
{  | 
	
  | 
return (lhs < rhs) ? lhs : rhs  | 
	
  | 
}  | 
	
  | 
  | 
	
  | 
Правила форматирования
Пробелы и просветы
16.Ставьте пробелы:
●после ключевых слов языка
●после запятой
●после точки с запятой в инструкции цикла for
●до и после оператора
  | 
	
  | 
	
  | 
	
  | 
	ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
|
  | 
	
  | 
	
  | 
	
  | 
	
  | 
	
  | 
|
a =  | 
	(b +  | 
	c)  | 
	* d;  | 
	
  | 
	a=(b+c)*d;  | 
|
  | 
	
  | 
	
  | 
	
  | 
	
  | 
||
while (bGo)  | 
	
  | 
	
  | 
	
  | 
	while(bGo)  | 
||
  | 
	
  | 
	
  | 
	
  | 
|||
doSomething(a,  | 
	b, c,  | 
	d);  | 
	doSomething(a,b,c,d);  | 
|||
  | 
	
  | 
	
  | 
	
  | 
	
  | 
	
  | 
	
  | 
for  | 
	(i =  | 
	0;  | 
	(i  | 
	< 10)  | 
	&& bGo; i++)  | 
	for(i=0;i<10 && bGo;i++)  | 
  | 
	
  | 
	
  | 
	
  | 
	
  | 
	
  | 
	
  | 
Перечисление всех ситуаций, когда необходимо ставить пробел, не является полным.
17.Разделяйте логически связанные части исходного кода одной пустой строкой.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
double cosAngle = Math.cos(angle);  | 
	double cosAngle = Math.cos(angle);  | 
double sinAngle = Math.sin(angle);  | 
	double sinAngle = Math.sin(angle);  | 
  | 
	Matrix4x4 matrix = new Matrix4x4();  | 
Matrix4x4 matrix = new Matrix4x4();  | 
	matrix.setElement(1, 1, cosAngle);  | 
matrix.setElement(1, 1, cosAngle);  | 
	matrix.setElement(1, 2, sinAngle);  | 
matrix.setElement(1, 2, sinAngle);  | 
	matrix.setElement(2, 1, -sinAngle);  | 
matrix.setElement(2, 1, -sinAngle);  | 
	matrix.setElement(2, 2, cosAngle);  | 
matrix.setElement(2, 2, cosAngle);  | 
	multiply(matrix);  | 
multiply(matrix);  | 
	
  | 
  | 
	
  | 
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 5 из 23  | 
18.Разделяйте определения функции тремя пустыми строками.  | 
	
  | 
|
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
	
  | 
  | 
	
  | 
	
  | 
void  | 
	void  | 
	
  | 
funcA()  | 
	funcA()  | 
	
  | 
{  | 
	{  | 
	
  | 
// ...  | 
	// ...  | 
	
  | 
}  | 
	}  | 
	
  | 
  | 
	void  | 
	
  | 
  | 
	funcB()  | 
	
  | 
void  | 
	{  | 
	
  | 
funcB()  | 
	// ...  | 
	
  | 
{  | 
	}  | 
	
  | 
// ...  | 
	
  | 
	
  | 
}  | 
	
  | 
	
  | 
  | 
	
  | 
	
  | 
void  | 
	void  | 
	
  | 
СMainWindow::funcA()  | 
	СMainWindow::funcA()  | 
	
  | 
{  | 
	{  | 
	
  | 
// ...  | 
	// ...  | 
	
  | 
}  | 
	}  | 
	
  | 
  | 
	void  | 
	
  | 
  | 
	СMainWindow::funcB()  | 
	
  | 
  | 
	{  | 
	
  | 
void  | 
	// ...  | 
	
  | 
СMainWindow::funcB()  | 
	}  | 
	
  | 
{  | 
	
  | 
	
  | 
// ...  | 
	
  | 
	
  | 
}  | 
	
  | 
	
  | 
  | 
	
  | 
	
  | 
19.Используйте отличные от рекомендуемого форматирование только в том случае, если его использование существенно улучшает читаемость кода.
  | 
	ПРИМЕР  | 
	
  | 
  | 
	
  | 
	
  | 
switch (typePhase)  | 
	
  | 
	
  | 
{  | 
	
  | 
	
  | 
case PHASE_PRE  | 
	: start(phase, "Pre");  | 
	break;  | 
case PHASE_COMMON  | 
	: start(phase, "Common");  | 
	break;  | 
case PHASE_POST  | 
	: start(phase, "Post");  | 
	break;  | 
}  | 
	
  | 
	
  | 
  | 
	
  | 
	
  | 
Отступы
20.Основной отступ составляет 4 пробела.
  | 
	
  | 
	ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
	
  | 
	
  | 
for (i =  | 
	0; i  | 
	< nElements; i++)  | 
	for (i = 0; i < nElements; i++)  | 
{  | 
	
  | 
	
  | 
	{  | 
a[i]  | 
	= 0;  | 
	
  | 
	a[i] = 0;  | 
}  | 
	
  | 
	
  | 
	}  | 
  | 
	
  | 
	
  | 
	
  | 
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 6 из 23  | 
21.В определении функции размещайте тип возвращаемого значения на отдельной строке.  | 
||
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
	
  | 
  | 
	
  | 
	
  | 
int  | 
	int findMedian("arguments")  | 
	
  | 
findMedian("arguments")  | 
	
  | 
	
  | 
  | 
	
  | 
|
void  | 
	void MyClass::myMethod("arguments")  | 
|
MyClass::myMethod("arguments")  | 
	{  | 
	
  | 
{  | 
	"statements";  | 
	
  | 
"statements";  | 
	}  | 
	
  | 
}  | 
	
  | 
	
  | 
  | 
	
  | 
	
  | 
22.Выравнивайте скобки начала и конца блока и располагайте их в отдельных строках. Тело блока размещайте с основным отступом относительно границ блока.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
"statement"  | 
	"statement" {  | 
{  | 
	"statements";  | 
"statements";  | 
	}  | 
}  | 
	
  | 
  | 
	
  | 
23.Логические блоки (if, else) оформляются в соответствии с общим принципом оформления блоков следующим образом.
ПРИМЕР
if ("condition")
{
"statements";
}
if ("condition")
{
"statements";
}
else
{
"statements";
}
if ("condition")
{
"statements";
}
else if ("condition")
{
"statements";
}
else
{
"statements";
}
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 7 из 23  | 
24.Цикл for оформляется в соответствии с общим принципом оформления блоков следующим образом.
ПРИМЕР
for ("initialization"; "condition"; "update")
{
"statements";
}
25.Цикл while оформлятеся в соответствии с общим принципом оформления блоков следующим образом.
ПРИМЕР
while ("condition")
{
"statements";
}
26.Цикл do - while оформлятеся в соответствии с общим принципом оформления блоков следующим образом.
ПРИМЕР
do
{
"statements";
} while ("condition");
27.Выбор switch оформляется следующим образом.
ПРИМЕР
switch ("condition")
{
case DEF: "statements"; break;
case XYZ: "statements"; break;
default:
"statements";
break;
}
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 8 из 23  | 
|
28.Оформляйте всегда в блок пустые и однострочные тела циклов и т.д.  | 
	
  | 
||
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
	
  | 
|
  | 
	
  | 
	
  | 
|
if ("condition")  | 
	if ("condition")  | 
	
  | 
|
{  | 
	selectBest(prop, pData);  | 
	
  | 
|
selectBest(prop, pData);  | 
	
  | 
	
  | 
|
}  | 
	
  | 
	
  | 
|
  | 
	
  | 
	
  | 
|
if ("condition")  | 
	if ("condition")  | 
	
  | 
|
{  | 
	selectBest(prop, pData);  | 
	
  | 
|
selectBest(prop, pData);  | 
	else  | 
	
  | 
|
}  | 
	selectWorst(prop, pData);  | 
	
  | 
|
else  | 
	
  | 
	
  | 
|
if ("condition") selectBest(prop,  | 
|||
{  | 
|||
pData);  | 
	
  | 
||
selectWorst(prop, pData);  | 
	
  | 
||
else selectWorst(prop, pData);  | 
|||
}  | 
|||
  | 
	
  | 
||
  | 
	
  | 
	
  | 
|
while (!done)  | 
	while (!done) doSomething();  | 
	
  | 
|
{  | 
	
  | 
	
  | 
|
while (!done)  | 
	
  | 
||
doSomething();  | 
	
  | 
||
doSomething();  | 
	
  | 
||
}  | 
	
  | 
||
  | 
	
  | 
||
  | 
	
  | 
	
  | 
|
Пустой цикл оформляется следующим образом  | 
	
  | 
	
  | 
|
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
	
  | 
|
  | 
	
  | 
||
for ("init"; "cond"; "update")  | 
	for ("init"; "cond"; "update");  | 
||
{  | 
	
  | 
	
  | 
|
for ("init"; "condition"; "update") {}  | 
|||
}  | 
|||
  | 
	
  | 
||
  | 
	
  | 
	
  | 
|
Структурированость кода
29.Размещайте не более одной инструкции в одной строке (в строке не больше одной ';', кроме случая цикла for)
  | 
	ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
	
  | 
int  | 
	i(0);  | 
	int i(0); findBorder(&i);  | 
findBorder(&i);  | 
	
  | 
|
  | 
	
  | 
|
30.Размещайте не более одного оператора присваивания в строке.  | 
||
  | 
	ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
	
  | 
a =  | 
	0;  | 
	a = b = 0;  | 
b =  | 
	0;  | 
	
  | 
  | 
	
  | 
	
  | 
31.Полагайтесь на приоритет только арифметических операторов. Используйте скобки для выделения частей выражений и указания приоритета вычислений.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
a = b & (c | e) & d;  | 
	a = b & c | e & d;  | 
  | 
	
  | 
32.Избегайте длинных функций. Длинными считаются функции более 180 строк.
33.Избегайте длинных файлов. Длинными считаются файлы более 1000 строк.
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 9 из 23  | 
Комментарии
34.Пишите все комментарии на русском языке.
35.В начало каждого файла исходного текста вставляйте описание по следующему шаблону (имя самого файла, краткое описание, автор, дата создания).
/**  | 
	
  | 
\file  | 
	имя файла  | 
\brief  | 
	краткое описание содержимого файла  | 
\author  | 
	ФИО автора  | 
\date  | 
	дата создания файла  | 
*/  | 
	
  | 
  | 
	
  | 
  | 
	
  | 
  | 
	ПРИМЕР  | 
  | 
	
  | 
/**  | 
	
  | 
\file  | 
	codedialog.h  | 
\brief  | 
	Класс диалога выбора входящего номера  | 
\author  | 
	Полевой Дмитрий  | 
\date  | 
	04.09.2004  | 
*/  | 
	
  | 
  | 
	
  | 
36.Комментируйте объявление каждой функции с использованием следующего шаблона.
ШАБЛОН
/**
\brief краткое описание функции
\param описание каждого параметра (имя [in/out] - описание) \retval TYPE, основные значения
*/
  | 
	
  | 
	ПРИМЕР  | 
  | 
	
  | 
	
  | 
/**  | 
	
  | 
	
  | 
\brief Функция позволяющая  | 
	пользователю выбрать в диалоге папку  | 
|
\param pUserPromt  | 
	[in]  | 
	- текст, который будет отображаться над деревом  | 
папок (подсказка)  | 
	
  | 
	
  | 
\param pFilePath  | 
	[in/out]  | 
	- папка. В диалоге выбранная папка сначала будет  | 
pPath. Если пользователь нажал "OK", то в szPath запишется выбранная  | 
||
пользователем папка  | 
	
  | 
|
\param lenPath  | 
	[in]  | 
	- размер буфера pFilePath  | 
\param pRootPath  | 
	[in]  | 
	- путь к корневой папке, в которой пользователь  | 
будет выбирать  | 
	
  | 
	
  | 
\retval bool - true, если удалось, иначе false */
bool
GetFolder(const char* pUserPromt, char* pPath, size_t int lenPath, const char* pRootPath);
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
M102 (Правила кодирования,Полевой Д.В.)  | 
	05.02.10  | 
	стр. 10 из 23  | 
|
37.Комментарии пишутся с отступом комментируемого кода.  | 
	
  | 
||
ПРАВИЛЬНО  | 
	
  | 
	НЕПРАВИЛЬНО  | 
	
  | 
  | 
	
  | 
	
  | 
	
  | 
// Найдем среднее значение  | 
	
  | 
	// Найдем среднее значение  | 
	
  | 
for (int iRow(0); iRow != nRow;  | 
	
  | 
	for (int iRow(0); iRow != nRow;  | 
|
++iRow)  | 
	
  | 
	++iRow)  | 
	
  | 
// По строкам таблицы.  | 
	
  | 
	// По строкам таблицы.  | 
	
  | 
{  | 
	
  | 
	{  | 
	
  | 
// Накопитель суммы по строке.  | 
	
  | 
	// Накопитель суммы по строке.  | 
|
int totalValue(0);  | 
	
  | 
	int totalValue(0);  | 
	
  | 
"statements";  | 
	
  | 
	"statements";  | 
	
  | 
}  | 
	
  | 
	}  | 
	
  | 
  | 
	
  | 
	
  | 
|
38.Размещайте комментарии либо до комментируемого фрагмента, либо в конце  | 
	
  | 
||
комментируемой строки по следующему образцу.  | 
	
  | 
||
  | 
	ПРИМЕР  | 
	
  | 
|
  | 
	
  | 
||
/// Главный цикл перебора компонент из хранилища.  | 
	
  | 
||
for (indexComp = 0; indexComp < MAX_COMP; ++indexComp)  | 
	
  | 
||
  | 
	
  | 
||
int userId(0); ///< Идентификатор пользователя АСУ.  | 
	
  | 
||
  | 
	
  | 
	
  | 
	
  | 
39.Описывайте в комментариях назначение переменных.
40.Наличие комментариев не освобождает от ответственности за излишне сложный код — изощренный код должен быть переписан, а не задокументирован.
41.Избегайте использования комментариев для отключения больших кусков кода.
Правила именования
Общие правила
42.Все имена и идентификаторы пишутся на английском (без использования транслитерации и т.д.).
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
fileName  | 
	imyaFayla  | 
  | 
	
  | 
43.Избегайте запрещенных идентификаторов для имен.
Запрещено начинать имена с подчеркивания (резервируется для реализации компиляторов).
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
fileName_  | 
	_fileName  | 
  | 
	
  | 
44.Пишите имена типов (в т.ч. псевдонимы typedef) в смешанном регистре начиная с символа верхнего регистра.
ПРАВИЛЬНО  | 
	НЕПРАВИЛЬНО  | 
  | 
	
  | 
CFastString  | 
	fast_string  | 
  | 
	
  | 
  | 
	fastString  | 
  | 
	
  | 
  | 
	FastString  | 
  | 
	
  | 
предложения/пожелания и сообщения об очепятках присылать на oop.misis [тузик] gmail.com
