Pull to refresh

С++0x и решение проблем инициализации

Reading time 3 min
Views 3.1K
C++0xВ статьях на хабре уже касались стандарта С++0x, а в частности лямбда-выражений. Я хотел написать еще про пару изменений и дополнений, которые внесут в С++. И без лишних слов сразу к делу.


Инициализация целочисленных переменных


С++0x решает проблему приведения элементраных вешественных типов к целочисленным. На простейшем примере это выглядит так:

Классический С++:

int a = 7.3;    //Приведение к int все равно сработает
void func(int);
func(5.6);      //И снова сработало приведение типов без нашего разрешения



В С++0x проблема решается с помощью введения новой конструкции для {}:

int x1 = {7.3};    //Ошибка приведения типов - и ошибка компиляции
double d = 7;
int x2 {d};      //И снова нельзя, произойдет ошибка
char x3{7};      //Все нормально
vector<int> vi = { 1, 2.3, 4, 5.6 };  //Не получится, так как нет соответствия



Делегирование конструкторов


В С++ необходимо иметь два конструктора для выполнения практически одинаковых действий или использовать дополнительную функцию.

Классический С++:

class X
{
  int a;
  validate(int x)
  {
    if (0<x && x<=max) a=x;
    else throw bad_X(x);
  }

public:
  X(int x)    //Конструктор с входным параметром типа int
  {
    validate(x);
  }

  X()        //Конструктор по-умолчанию
  {
    validate(42);
  }

  X(string s)    //Конструктор с входным параметром типа string
  {
    int x = lexical_cast<int>(s);
    validate(x);
  }
  // ...
};



В С++0x один конструктор можно объявить в контексте другого конструктора:

class X
{
  int a;

public:

  X(int x)    //Конструктор с входным параметром типа int
  {
    if (0<x && x<=max) a=x;
    else throw bad_X(x);
  }
  
  X() :X{42} { }    //Конструктор по-умолчанию
    
  X(string s) :X{lexical_cast<int>(s)} { }  //Конструктор с входным параметром типа string
  
  // ...
}



Нулевые указатели



В стандартном С++ нулевой указатель представляет из себя обычный 0. В библиотеках можно встретить #define NULL 0. В С++0x вводится специальный литерал nullptr.

Пример использования:

char* p = nullptr;
int* q = nullptr;
char* p2 = 0;    //Можно и по-старинке

void f(int);    //Функция с входным параметром int
void f(char*);    //Функция с входным параметром char*

f(0);        //вызов f(int) - все нормально
f(nullptr);      //вызов f(char*) - все нормально

void g(int);
g(nullptr);      //Облом: nullptr не является int
int i = nullptr;  //И снова облом



Заключиние


Изменения, конечно, немного косметические, но делают язык более безопасным и удобным, а главное — не выглядят так экстремально, как лямбда-выражения ).

Продолжение следует…

Progg it
Tags:
Hubs:
+32
Comments 38
Comments Comments 38

Articles