Copy initialization vs direct initialization khác nhau chỗ nào năm 2024

C++11 introduced the uniform initialization syntax using braced initializer lists. You have direct list initialization which does not include an equal sign, for example:

int myInt{42};

and you have copy list initialization which uses the equal sign, for example:

int myInt = {42};

The auto type deduction rules have changes in C++17. With C++17, if you use copy list initialization, then an initializer_list is deduced, for example:

auto initList1 = {42}; auto initList2 = {42, 84, 126};

All values in the braced initializer list must be of the same type. The following does not compile:

auto initList2 = {42, 84.42};

When you use direct list initialization, then a value is deduced. For example, the following deduces an int:

auto anInt{42};

This also means that the following causes a compilation error because more than 1 initialization value is given:

auto ints{42, 84, 126};

This is the new C++17 behavior. With C++11/C++14, all of the above would deduce to an initializer_list.

Khi tất cả các biến thành viên của một class [hoặc struct] đều là public [công khai], chúng ta có thể sử dụng cú pháp khởi tạo tổng hợp [aggregate initialization] để khởi tạo trực tiếp class [hoặc struct] chúng ta có thể sử dụng cách khởi tạo bằng một danh sách [initialization list] hoặc khởi tạo đồng đều [uniform initialization]:

class Foo
{
public:
    int m_x;
    int m_y;
};
int main[]
{
    Foo foo1 = { 4, 5 }; // initialization list
    Foo foo2 { 6, 7 }; // uniform initialization
    return 0;
}

Tuy nhiên, ngay sau khi đặt bất kỳ biến thành viên nào thành private, chúng ta sẽ không còn có thể khởi tạo các class theo cách này nữa. Điều này là hợp lý bởi vì: Nếu bạn không thể truy cập trực tiếp vào một biến [bởi vì nó là private], thì bạn cũng không nên khởi tạo trực tiếp nó.

Vậy thì làm thế nào để chúng ta khởi tạo một class với các biến thành viên là private? Câu trả lời là thông qua các constructors – hàm khởi tạo.

Nội dung chính

Constructor là một loại hàm thành viên đặc biệt của class, được gọi tự động khi một đối tượng của class đó được khởi tạo. Các constructors thường được sử dụng để khởi tạo các biến thành viên của class theo các giá trị mặc định phù hợp hoặc do người dùng cung cấp, hoặc để thực hiện bất kỳ các bước thiết lập cần thiết nào cho class [ví dụ: Mở file hoặc cơ sở dữ liệu].

Không giống như các hàm thành viên thông thường, các hàm constructors có các quy tắc riêng về việc đặt tên:

  • Các hàm constructors phải có cùng tên với tên class [phải giống cả về việc ký tự viết hoa hay viết thường]
  • Các hàm constructor không có kiểu trả về [kể cả là kiểu void]

2. Constructors mặc định

Một constructor không có tham số truyền vào [hoặc có tham số mà tất cả chúng đều có giá trị mặc định] được gọi là constructor mặc định. Khi sử dụng một constructor, nếu không có giá trị khởi tạo nào do người dùng cung cấp được truyền cho constructor này, thì constructor mặc định sẽ được gọi.

Dưới đây là ví dụ về một class có một constructor mặc định:

/**
  • Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam *
  • @author cafedevn
  • Contact: cafedevn@gmail.com
  • Fanpage: //www.facebook.com/cafedevn
  • Instagram: //instagram.com/cafedevn
  • Twitter: //twitter.com/CafedeVn
  • Linkedin: //www.linkedin.com/in/cafe-dev-407054199/ */
# include class Fraction { private: int m_numerator; int m_denominator; public: Fraction[] // default constructor { m_numerator = 0; m_denominator = 1; } int getNumerator[] { return m_numerator; } int getDenominator[] { return m_denominator; } double getValue[] { return static_cast[m_numerator] / m_denominator; } }; int main[] { Fraction frac; // Since no arguments, calls Fraction[] default constructor std::cout

Chủ Đề