STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • 0
    • Sao chép

    Các Phương Thức Khởi Tạo Đối Tượng trong C++

    Giới thiệu và hướng dẫn sử dụng 3 phương pháp khởi tạo đối tượng với C++11 (C++0x): Contructor, Copy Constructor, Move Constructor.
    15/09/2014
    19/09/2020
    4 phút đọc
    Các Phương Thức Khởi Tạo Đối Tượng trong C++

    Giới thiệu

    Trước C++11 có 2 phương pháp khởi tạo giá trị cho đối tượng là Constructor và Copy Constructor, đến C++11 xuất hiện thêm Move Sematics, từ đó xuất hiện thêm loại constructor thứ 3 - Move Constructor.

    Như vậy, hiện tại C++11 trở về sau hỗ trợ 3 loại constructor với mục đích sử dụng khác nhau nhằm tối ưu hóa cho từng trường hợp sử dụng cụ thể:

    • Constructor: hàm tạo khởi tạo mới.
    • Copy constructor: hàm tạo sao chép.
    • Move constructor: hàm tạo dịch chuyển.

    Ứng với 3 tên gọi này là mục đích sử dụng của nó. Cả 3 phương thức đều tự động gọi khi đối tượng được tạo ra.

    Constructor là gì?

    Constructor là phương thức khởi tạo khi muốn tạo 1 đối tượng độc lập và mới hoàn toàn.

    Copy constructor là gì?

    Copy constructor là phương thức khởi tạo khi muốn tạo 1 đối tượng và tại thời điểm khởi tạo sẽ sao chép dữ liệu từ 1 đối tượng cùng kiểu.

    Move constructor là gì?

    Move constructor là phương thức khởi tạo khi muốn tạo 1 đối tượng và tại thời điểm khởi tạo sẽ lấy dữ liệu từ đối tượng có cùng kiểu.

    Các trường hợp sử dụng

    Để hiểu được cách sử dụng của 3 loại constructor trên, xét ví dụ cụ thể trong trường hợp ma trận 4x4:

    #include <string.h>
    
    class Matrix4x4
    {
    private:
        double* data;
    
    public:
        Matrix4x4()
        {
            data = new double[4 * 4];
        }
    
        Matrix4x4(const Matrix4x4& matrix)
        {
            data = new double[4 * 4];
            memcpy(data, matrix.data, sizeof(double) * 4 * 4);
        }
    
        Matrix4x4(Matrix4x4&& matrix)
        {
            data = matrix.data;
            matrix.data = nullptr;
        }
    
        ~Matrix4x4()
        {
            if (data != nullptr)
                delete[] data;
        }
    
        Matrix4x4& operator=(const Matrix4x4& matrix)
        {
            memcpy(data, matrix.data, sizeof(double) * 4 * 4);
            return *this;
        }
    
        Matrix4x4 operator+(const Matrix4x4& matrix)
        {
            Matrix4x4 result = *this;
            for (int i = 0; i < 4 * 4; i++)
                result.data[i] += matrix.data[i];
            return result;
        }
    };
    int main() { Matrix4x4 m1, m2; Matrix4x4 m3 = m1 + m2; return 0; }

    Matrix4x4()

    Constructor được gọi trong trường hợp tạo mới 1 Matrix4x4 không truyền đối tượng Matrix4x4 khác. Ví dụ:

    Matrix4x4 m1;
    Matrix4x4 m2;

    Constructor được sử dụng trong trường hợp tạo mới 1 Matrix4x4 và không có nhu cầu sao chép bất kỳ dữ liệu nào từ các đối tượng Matrix4x4 có sẵn.

    Matrix4x4(const Matrix4x4 & matrix)

    Copy constructor được gọi trong trường hợp khởi tạo đối tượng truyền vào 1 lvalue có kiểu là Matrix4x4. Ví dụ khởi tạo m2 và gọi copy constructor để sao chép giá trị của m1.

    Matrix4x4 m1;
    Matrix4x4 m2(m1); // hoặc Matrix4x4 m2 = m1;

    Copy constructor được sử dụng trong trường hợp tạo các giá trị mới nhưng cần sao chép ngay các dữ liệu của đối tượng có sẵn thay vì gọi constructor tốn kém hiệu năng và rồi gọi phương thức sao chép tốn kém thêm 1 lần hiệu năng nữa.

    1 trường hợp điển hình sử dụng copy constructor thuận tiện là hoán đổi giá trị của 2 Matrix4x4 khi cần khai báo 1 Matrix4x4 temp.

    Matrix4x4 temp = m1;
    m1 = m2;
    m2 = temp;

    Dòng Matrix4x4 temp = m1 gọi copy constructor khi khởi tạo temp, trường hợp này dùng vậy rất thuật tiện và đỡ tốn hiệu năng.

    Matrix4x4(Matrix4x4 && matrix)

    Move constructor được gọi trong trường hợp khởi tạo đối tượng truyền vào 1 rvalue.

    Matrix4x4 m1, m2;
    Matrix4x4 m3(m1 + m2);

    Dòng Matrix4x4 m3(m1 + m2) trong đó m1 + m2 sẽ trả về 1 đối tượng tạm, sau dòng code này đối tượng đó sẽ hủy, trước C++11 chỉ có thể gọi copy constructor, m3 sẽ phải khởi khởi tạo vùng nhớ và sao chép dữ liệu từ đối tượng m1 + m2 dù biết rằng m1 + m2 sẽ không dùng nữa nhưng vẫn không thể "chiếm dụng" kết quả này, nhưng với C++11 thì khác, có thể tiến hành gọi move constructor vì biết m1 + m2 là rvalue, như phần hiện thực của move constructor có thể thấy dữ liệu tạm được "sang nhượng" cho m3. với chi phí thấp hơn copy constructor.

    0
    Modern C++

    Modern C++

    STDIO Training - Đào Tạo Lập Trình C++.

    Khi bạn nhấn vào liên kết sản phẩm do STDIO đề xuất và mua hàng, STDIO có thể nhận được hoa hồng. Điều này hỗ trợ STDIO tạo thêm nhiều nội dung hữu ích.. Tìm hiểu thêm.

    Đề xuất

    Sự Ra Đời Của Phương Thức Khởi Tạo (Constructor), Phương Thức Hủy (Destructor) Trong Một Class - C++
    Tìm hiểu về phương thức khởi tạo (Constructor) và phương thức hủy ...
    12/09/2014
    Khởi Tạo Đối Tượng trong Runtime
    Hướng dẫn thao tác khởi tạo đối tượng trong Runtime - thời điểm chạy ...

    Khám phá

    9 Tính Năng Quan Trọng Trong C++11
    C++11 là một phiên bản cải tiến và nâng cấp từ C++98 (hay các bạn vẫn ...
    13/08/2015
    Thành Phần Hoá Các Đối Tượng Trong Game Với Cocos2d-x
    Hướng dẫn thành phần hoá các đối tượng trong game với Cocos2d-x
    Lập Trình Hướng Đối Tượng Trong Python  - Phần 1: Cơ Bản
    Đặc điểm và cách hiện thực lập trình hướng đối tượng trong Python.
    29/03/2015
    Quản Lý Vị Trí Các Đối Tượng trong Game
    Cấu hình vị trí của các đối tượng trong Game để quản lý game đa màn ...
    Virtual Table Và Hiện Thực Hóa Polymorphism
    Cơ chế vận hành của phương thức ảo, tính đa hình trong lập trình hướng ...
    Giới Thiệu Về Sprite Trong Cocos2d-x 3.x.x
    Giới thiệu tổng quan về khái niệm cơ bản, một số cách dùng để khởi tạo ...
    Ghi Đè Phương Thức - Overriding Method trong Java
    Trong Java, ghi đè phương thức - overriding method là phương pháp "viết ...
    27/05/2015
    Chipmunk - Phần 6: Tạo Physics Body Cho Các Đối Tượng Có Hình Dạng Phức Tạp
    Kĩ thuật tạo Physics Body cho các đối tượng có hình khối phức tạp trong ...
    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020