0

Memory Layout của class

Khi học CPP, tôi thắc mắc là một class chứa các biến và method của nó thì có thực sự nằm chung trong vùng nhớ liên tiếp hay không? Mọi thứ của class được biểu diễn như thế nào trong memory .

Sau đây là một ví dụ, để xem được những gì thực sự đang chứa bên trong của một class

#include <iostream>

class LayoutMemory {
private:
    int private_var;       

protected:
    double protected_var; 

public:
    char public_var;      

    // Code Segment
    void method() {
        // Do something
    }

    // Data Segment
    static void static_method() {
        // Do something
    }

    // Hàm dùng để in ra mọi bí mật của class
    void print_address_all() {
        std::cout << "=== 1. DIA CHI OBJECT ===\n";
        std::cout << "Con tro 'this' (Dia chi goc): " << this << "\n\n";

        std::cout << "=== 2. DIA CHI CAC VAR  ===\n";
        std::cout << "private_var   (int)   : " << (void*)&private_var << "\n";
        std::cout << "protected_var (double): " << (void*)&protected_var << "\n";
        std::cout << "public_var    (char)  : " << (void*)&public_var << "\n";

        std::cout << "=== 3. DIA CHI CAC METHOD ===\n";
        
        // Address of static func 
        std::cout << "static_method()   : " << (void*)&LayoutMemory::static_method << "\n";

        auto ptr_ham = &LayoutMemory::method;
        std::cout << "method() : " << reinterpret_cast<void*&>(ptr_ham) << "\n";
    }
};

int main() {
    LayoutMemory obj1;
    LayoutMemory obj2;

    std::cout << ">>> MEMORY LAYOUT CUA OBJECT 1 <<<\n";
    obj1.print_address_all();

    std::cout << "\n----------------------------------------\n";

    std::cout << "\n>>> MEMORY LAYOUT CUA OBJECT 2 <<<\n";
    obj2.print_address_all();

    return 0;
}

Output

>>> MEMORY LAYOUT CUA OBJECT 1 <<<
=== 1. DIA CHI OBJECT ===
Con tro 'this' (Dia chi goc): 0x7ffdfb4b8980

=== 2. DIA CHI CAC VAR  ===
private_var   (int)   : 0x7ffdfb4b8980
protected_var (double): 0x7ffdfb4b8988
public_var    (char)  : 0x7ffdfb4b8990
=== 3. DIA CHI CAC METHOD ===
static_method()   : 0x558cc4c76231
method() : 0x558cc4c76222

----------------------------------------

>>> MEMORY LAYOUT CUA OBJECT 2 <<<
=== 1. DIA CHI OBJECT ===
Con tro 'this' (Dia chi goc): 0x7ffdfb4b89a0

=== 2. DIA CHI CAC VAR  ===
private_var   (int)   : 0x7ffdfb4b89a0
protected_var (double): 0x7ffdfb4b89a8
public_var    (char)  : 0x7ffdfb4b89b0
=== 3. DIA CHI CAC METHOD ===
static_method()   : 0x558cc4c76231
method() : 0x558cc4c76222

Kết luận rút ra từ bộ nhớ của Class:

  • Class thực chất chỉ là một vùng nhớ chứa các biến: Nó không hề chứa các phương thức (method) bên trong. Các biến này được nằm nối tiếp nhau giống hệt như một struct.
  • Quyền truy cập (private/protected/public): Dù là private hay public, chúng đều nằm san sát nhau trong bộ nhớ. Các từ khóa này thực chất chỉ là "hàng rào bảo vệ" do trình biên dịch (compiler) dựng lên lúc viết code để ngăn ta truy cập sai nguyên tắc, chứ không làm thay đổi cấu trúc bộ nhớ.
  • Các method được đưa ra một vùng nhớ riêng biệt. Điều này mang lại lợi ích gì?
    • Lợi ích lớn nhất là tiết kiệm bộ nhớ: Thay vì mỗi object khi sinh ra đều phải "cõng" theo một bản sao của các hàm (gây lãng phí RAM khổng lồ mà mục đích hàm không đổi), thì C++ gom tất cả lại thành một bản duy nhất. Dù bạn có tạo ra object1, object2 hay hàng triệu object khác, chúng đều trỏ tới dùng chung một method này.

image.png


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí