10 Temmuz 2018 Salı

Brace Initialization

Giriş
C++11'de diziler, sınıflar, structlar ve değişkenler brace initialization ile ilklendirilebilir. Brace initialization genellikle

1. direct-list initialization
2. copy-list-initalization

olarak ikiye ayrılır

Uniform Kelimesi Daha İyi Olurdu
Ben C++11 ile gelen bu kavram için uniform initialization kelimesinini daha uygun olduğunu düşünüyorum. Ancak yazıda brace initialization kelimesini kullanacağım.

Gramer olarak şöyle kullanılıyor.

initializer:
  brace-or-equal-initializer
  ( expression-list )

brace-or-equal-initializer:
  = initializer-clause
  braced-init-list

initializer-clause:
  assignment-expression
  braced-init-list
initializer-list:
  initializer-clause...opt
  initializer-list,initializer-clause...opt

braced-init-list:
  {initializer-list,opt}
  { }
Integral Tipler
Sıfır ile doldurulur.
int i{};
double x{};
Aggregate Tipler
Brace Initialization - Aggregate yazısına taşıdım.

Auto Tipler
C++17'den Sonra
Açıklaması şöyle. C++17'den sonra liste tek bir eleman alacak hale getirildi.
(since C++17)
In direct-list-initialization (but not in copy-list-initalization), when deducing the meaning of the auto from a braced-init-list, the braced-init-list must contain only one element, and the type of auto will be the type of that element:
Şöyle yaparız
auto x1 = {3}; // x1 is std::initializer_list<int>
auto x2{1, 2}; // error: not a single element
auto x3{3};    // x3 is int
               // (before C++17 x2 and x3 were both std::initializer_list<int>)

C++17'den Önce
Şöyle yaparız.
auto x1 {1,2,3,4}; // x1 is an initializer_list<int>
auto x2 {1.0, 2.25, 3.5 }; // x2 is an initializer_list of<double>
Class Tipler
Brace Initialization - Object yazısına taşıdım.

Diğer

Default Initialization
Açıklaması şöyle.
If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced
Örnek
Şöyle yaparız.
class Number
{
  int number;
public:
  Number(std::string s)
  {
    if (s == "foo")
    {
      number = 10;
    }
  }
};

Number n("bar");
std::cout << n.getNumber() << std::endl;
List Initialization
Eğer narrowing varsa derleyicisine göre uyarı veya hataya sebep olur. Şöyle yaparız.
class A
{
  public:
    A(const unsigned int val) : value(val) {}

    unsigned int value;
};

int main()
{
  int val = 42;
  A a(val);
  A b{val};       // <--- Warning in GCC, error in Microsoft Visual Studio 2015

  return 0;
}
List initialization kullanmayan eksi kodlarda sorun olmuyor. Şöyle yaparız.
int val = 42;
A a(val);
A a = val;
Value Initialization
Value initialization ve list initialization birbirlerine çok benziyor.Aradaki fark şöyle.
List-initialization of an object or reference of type T is defined as follows:
  • ...
  • Otherwise, if the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
Örnek
Eğer default constructor içinde her üye alanı bir değere eşitlenmezde tehlikeli olabilir. Şöyle yaparız.
class MyTest {
private:
  const static unsigned int dimension = 8;
  void (* myFunctions [dimension])();

public: 
  MyTest() {}

  void print() { 
    for(unsigned int i=0; i < MyTest::dimension; i++) {
      printf("myFunctions[%d] = %p\n", i, this->myFunctions[i]);
    }   
  }
};
Şöyle yaparız.
int main() {
  //We declare and initialize an object on the stack 
  MyTest testObj = {};
  testObj.print();

  return 0;
}
Çıktı olarak rastgelen değerler alırız.
myFunctions[0] = 76dd6b7d
myFunctions[1] = 00401950
myFunctions[2] = 0061ff94
myFunctions[3] = 004019ab
myFunctions[4] = 00401950
myFunctions[5] = 00000000
myFunctions[6] = 003cf000
myFunctions[7] = 00400080

Hiç yorum yok:

Yorum Gönder