OpenSCADAWiki: Roman Savochenko/C Short All/part1/part3 ...

Home | Index | Changes | Comments | Users | Registration | Login  Password:  
 

1.3 Переменные

1.3.1 Основные типы переменных


Таблица 3. Основные типы переменных языка С/С++
Тип (байт_сист)
Диапазон значений
Граничные постоянные <limits.h>
bool (1) false=0; true=1
char (1) -128...127 CHAR_MIN...CHAR_MAX, CHAR_BIT
int (2_16) -32.768...32.767 INT_MIN...INT_MAX
int (4_32) -231 ... 231 INT_MIN...INT_MAX
short -32.768...32.767 SHRT_MIN...SHRT_MAX
long (4_32) -231 ... 231 LONG_MIN...LONG_MAX
long (8_64) -263 ... 263 LONG_MIN...LONG_MAX
long long (8) -263 ... 263 LLONG_MIN...LLONG_MAX
unsigned char (1) 0 ...255 0...UCHAR_MAX
unsigned (2_16) 0 ...65535 0...UINT_MAX
unsigned (4_32) 0 ... 232 0...UINT_MAX
unsigned short (2) 0 ...65535 0...USHRT_MAX
unsigned long (4_32) 0 ... 232 0...ULONG_MAX
unsigned long (8_64) 0 ... 264 0...ULONG_MAX
unsigned long long (8) 0 ... 264 0...ULLONG_MAX
enum (2_16) 32.768...32.767
enum (4_32) -231 ... 231
float (4) 3.4*1038 (7 знаков)
double (8) 3.4*10308 (15 знаков)
long double (12) 3.4*104932 (19 знаков)

1.3.2 Перечислимый тип (enum)

Определяет тип enum и/или enum переменную. Если фигурные скобки заданы то ключевое слово enum объявляет тип, состоящий из набора именованных целочисленных констант. Таким образом, enum переменная всегда имеет тип int. Enum может использоваться, для объявления констант, которые могут использовать имена без объявления переменных для них, как показано в следующем примере:

enum DAYS 
{
  saturday, 
  sunday = 10,
  monday, 
  tuesday,
  wednesday,
  thursday,
  friday
} today; 
enum DAYS yesterday = monday;
DAYS yesterday = monday;     // C++
int tomorrow = wednesday;

1.3.3 Структура (struct)

Объявляет тип структуры и/или переменную структуры. Если заданы фигурные скобки то определяется структурный тип. Безымянные разрядные поля могут использоваться для выравнивания.
Если фигурные скобки не заданы то ключевое слово struct используется для определения переменной структуры. В языке C++ добавлена возможность использования в структуре ключевых слов public, private, protect:

struct my_str;  //my_str - как прототип, определена позже 
struct POINT  
{
   int x;
   int y;
} here = { 20, 40 };
POINT here1 = (POINT){ 21, 41 };
struct POINT there, *ther1;
ther1->x = 2;           
struct CELL  { //Выбор количества битов для элементов
    unsigned character  : 8;   // 00000000 ????????
    unsigned foreground : 3;   // 00000??? 00000000
    unsigned intensity  : 1;   // 0000?000 00000000
    unsigned blink      : 1;   // 000?0000 00000000
    unsigned :1                // заполнитель
} screen[25][80]; 
POINT example(POINT there)    

  there.x = 3;
  there.y = 5;
};

1.3.4 Тип объединение (union)

Объявляет тип - объединение, и/или переменную объединения. Если фигурные скобки заданы то, union объявляет тип объединения, состоящий из последовательности переменных, значения (известных как элементы объединения) которых могут иметь различные типы. Переменная типа union может содержать один элемент любого типа, определенного объединением. Размером объединения является размер самого большого типа в объединении. Переменная может быть определена, указанием ее имени после заключительной фигурной скобки. Если фигурные скобки не даны, то ключевое слово union используется, для определения переменной объединения. Например:

union UNKNOWN  
{
  char   ch;       
  int    i;
  long   l;
  float  f;
  double d; 
} var1;               // Variable of type UNKNOWN
union UNKNOWN var2;   // Variable of type UNKNOWN
var1.i = 6;           // Use variable as integer
var2.d = 5.327;       // Use variable as double

C++ Поддерживает анонимные объединения: 
union 
{   
   int my_data;
   float this_data;  
};
my_data=3

1.3.5 Пустой тип (void)

Если этот тип используется как тип возвращаемого значения функции то функция не возвращает значений. Если используется как список параметров функции, то входные параметры у функции отсутствуют (действительно только для С и не нужно в С++). Если используется указатель на тип void то его при использовании необходимо приводить к конкретному типу.

1.3.6 Сокращенный тип (typedef)

Описание typedef используется для замены сложных типов данных или создания своих специфических типов данных:

typedef  unsigned long int ULINT;
ULINT    my_const;

1.3.7 Тип класс (class)

Общие понятия

В С++ добавлен класс - расширение понятия структуры. Память при определении класса не выделяется. Класс имеет имя и состоит из полей, представляющих его члены. В С++ допускается использование вложенных классов. Ключевое слово public определяет те члены класса, к которым имеется прямой доступ. Ключевое слово private используется для сокрытия определенных деталей класса, которые доступны только функциям членам класса и дружественным функциям. Все члены класса по умолчанию считаются приватными. Ключевое слово protected используется для открытия доступа только членам этого класса и членам производных от него классов. Функции класса могут определятся как внутри (увеличивается объем программы и скорость выполнения) так и вне (уменьшается объем программы и скорость выполнения) его тела. При создании в программе объекта экземпляра, его членам присваиваются некоторые начальные значения эту операцию выполняет специальная функция - конструктор, имя которой совпадает с именем класса. Для освобождения памяти и других операций при закрытии класса используется деструктор имя которого совпадает с именем класса и с добавлением впереди символа "~".


Для присваивания переменной одного класса переменной другого класса можно в классе использовать оператор: operator char *() в котором описывается процедура преобразования одной переменной в другую что позволит в дальнейшем упростить обмен: title=big_book.


Одинаковые классы допускают копирования содержимого из одного класса в другой.


Конструкторы с одним параметром определённого типа могут использоваться для неявного преобразования типов (от типа параметра к типу класса). Для исключения этого нужно использовать директиву explicit.


class book 
{
  public:
    char title[256];
    char author[64];
    book(char *title="A", char *autor="B", 
         char *publisher= "C") 
    {
       strcpy(book::title, title);
       strcpy(book::author, author);
       strcpy(book::publisher, publisher);  
    }; 
    ~book(void);          
    char *get_price(*publisher) {*publisher};
    char show_title(void); 
  private:
    char publisher[256];
};
book diary;
book::~book(void) 
{
  cout << "Уничтожение экземпляра" << title << '\n';  };
  void book::show_title(void) {cout << title << '\n'; };
  book tips("Jamsa's 1001 C/C++", "Jamsa", "Jamsa Press");
}

Дружественные классы и члены

Дружественные классы - friend указывает на класс (или функцию), который может использовать private члены текущего класса. Есть возможность узкого указания на член класса friend имеющего доступ к private членам текущего класса. Кроме того есть возможность создавать взаимные friend - классы. Дружественная функция может не принадлежать ни какому классу, т.е быть автономной.

class book 
{
  public:
    char title[256];
    char author[64];
    friend class Reader::show_reader(class book book);
  private:
    char publisher[256];
};
class Reader {
  public:
    Reader (char *name) {strcpy(Reader::name, name); };
    void show_reader(class book book) 
    {cout<<"Читатель"<<name<<' '<< "Издательство"<<book.publisher; }; 
    class book tips[23];
  private:
    char name[64];
};

Наследование

Наследование это когда производный класс наследует свойства родительского класса. Наследование обеспечивает возможность рассмотрения порождённого объекта как базового (но не наоборот). Наследование может быть множественным. В производном классе допускается переопределение функций базового. Для обращения к перегруженной функции базового класса можно записать d.TBase::getData();, где TBase - имя базового класса. Наследования бывают:


class Cover 
{
  public:
     static int count;
     Cover(char *title) { strcpy(Cover::title, title) ;};
  protected:
     char title[256];
};  
class book 
{
  public: 
     book (char *title) {srcpy(book::title, title); };
     void show_title(void) {cout << title <<endl; };
  protected:
     float cost;
     void show_cost(void) {cout<<cost<<endl; };   
  private:
     char title[64];
};
class LibraryCard : public Cover, public book {
  public:
     LibraryCard(char *title, char *author, char *publisher):
     book(title)  
     {
        strcpy(LibraryCard::author, author);
        strcpy(LibraryCard::publisher, publisher);
        cost = 39.95; 
     };
  private:
     char author[64];
     char publisher[64];
};

Полиморфизм

В классах поддерживается позднее(динамическое) связывание посредством механизма виртуальных функций. Динамическое связывание(определение адресов вызываемых в программе функций) происходит во время выполнения программы. В программах могут использоваться объектные переменные, или объектные указатели, значения которых - указатели на объекты-экземпляры того или иного класса. В языке С++ разрешается использовать объектный указатель базового класса для указания объекта производного класса. В языке С++ полиморфизм обеспечивается использованием механизма виртуальных функций. Для обращения к членам базового и производного класса имеющим одинаковые имена, используется определение виртуальной функции - virtual, что заставляет обращаться к члену последнего активизированного класса. Для корректного удаления объектов из памяти можно создавать виртуальный деструктор который будет вызываться перед вызовом деструктора базового класса. Чистая виртуальная функция (приравнивается 0) является аналогом прототипа, который объявляется в базовом классе а описывается в производном классе. Класс в котором хотя бы одна виртуальная функция приравнена 0 - является абстрактной. Абстрактным также является класс у которого деструктор преравнен к 0, но всёже определён (используется для исключения прямого создания объекта данного класса). Конкретным является класс в котором все чисто виртуальные функции базового класса переопределены:


class Base
{
  public: 
    void base_mess(void) {cout<<"Base\n"; }; 
    virtual void show_mess(void) { cout<<"Base";};  
    virtual void show_reserve(void) = 0;   
};
class Der: public Base
{
  public: 
    void der_mess(void){       }; 
    virtual void show_mess(void) { cout<<"Der";};         
    virtual void show_reserve(void){ cout<<"           ";};  
};
void main(void) 

  Base *base_pointer = new Base;
  base_pointer->base_mess();
  base_pointer->show_mess();
  base_pointer = new Der;
  base_pointer->der_mess();
  base_pointer->show_mess();   
}

Инициализаторы

Для инициализации членов данных из конструктора можно использовать инициализаторы. Которые являются единственным способом инициализации константных членов класса:

class Time
{
  public: 
    Time();   
    const int time;
};
Time::Time() : time(10)
{...};

Композиция

Классы допускают композицию т.е включение одного объекта в другой. Включенные объекты уничтожаются после уничтожения содержащего их объекта.

class Time
{
  public: 
    Time();   
    const int time;
};
class Date
{
  public
    Date();
  private
    const Time time;
}
Date::Date : time()
{...};

Ссылка на себя

В классах есть возможность ссылаться на себя. Эта функция обеспечивается ключевым словом <this> которое содержит адрес текущего объекта. Может использоваться сцепления путём возврата адреса или ссылки объекта его членами функциями.

Proxy классы

Proxy классами называются классы которые призваны скрывать private члены классов закрытой реализации библиотеки. Создаются они путем создания указателя на скрываемый класс в private поле proxy класса:

class Sequry
{
  public
    void setValue(int x);
  private: 
    int value;   
};
class Proxy
{
  public
    setValue(int x) {ptr->setValue(x);};
  private
    Sequry *ptr;
}


 
There are no files on this page.[Display files/form]
There is no comment on this page. [Display comments/form]