Menu
CoddyTech

Con trỏ thông minh trong C++

Thuộc phần Lập trình hướng đối tượng trong hành trình C++ của Coddy. Bài học 15 trên 104.

Con trỏ thông minh là các lớp bao bọc tự động quản lý bộ nhớ heap cho bạn. Chúng loại bỏ nhu cầu gọi delete thủ công bằng cách giải phóng bộ nhớ khi con trỏ ra khỏi phạm vi.

Thêm header <memory> để sử dụng con trỏ thông minh.

unique_ptr - quyền sở hữu độc quyền. Mỗi lần chỉ một con trỏ có thể sở hữu tài nguyên.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Dùng như con trỏ thông thường

// Không thể sao chép, nhưng có thể chuyển quyền sở hữu
std::unique_ptr<Player> player2 = std::move(player);
// player giờ là nullptr

shared_ptr - quyền sở hữu chung. Nhiều con trỏ có thể cùng sở hữu một tài nguyên. Bộ nhớ được giải phóng khi chủ sở hữu cuối cùng bị hủy.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Cả hai cùng sở hữu tài nguyên

std::cout << p1.use_count();  // In ra 2

weak_ptr là đối tượng quan sát không sở hữu của shared_ptr. Hữu ích để phá vỡ các tham chiếu vòng.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // Chuyển sang shared_ptr
    locked->attack();
}

Mặc định, hãy dùng unique_ptr để sở hữu riêng. Dùng shared_ptr khi nhiều đối tượng cần cùng chia sẻ một tài nguyên. Dùng weak_ptr để theo dõi mà không kéo dài thời gian tồn tại.

Ưu tiên dùng make_unique và make_shared thay vì new thuần.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống chia sẻ tài liệu để minh họa các mô hình sở hữu khác nhau của con trỏ thông minh. Bạn sẽ thấy cách unique_ptr đảm bảo quyền sở hữu độc quyền, cách shared_ptr cho phép nhiều chủ sở hữu và cách weak_ptr có thể quan sát mà không ảnh hưởng đến thời gian tồn tại.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • Document.h: Định nghĩa một lớp Document đại diện cho tài liệu có thể chia sẻ. Lớp này cần có:
    • Thuộc tính title ở phạm vi private (chuỗi)
    • Hàm khởi tạo nhận tiêu đề và in ra "Document created: <title>"
    • Hàm hủy in ra "Document deleted: <title>"
    • Phương thức getTitle() trả về tiêu đề
  • main.cpp: Minh họa cả ba loại con trỏ thông minh bằng cách đọc tiêu đề tài liệu từ đầu vào, sau đó:
    • Tạo một unique_ptr trỏ đến một tài liệu có tiêu đề lấy từ đầu vào
    • In ra "Unique owner: <title>"
    • Chuyển quyền sở hữu sang một unique_ptr khác bằng std::move
    • In ra "Ownership transferred"
    • Tạo một shared_ptr trỏ đến tài liệu mới có tiêu đề "SharedDoc"
    • Tạo một shared_ptr thứ hai trỏ đến cùng tài liệu đó
    • In ra "Shared owners: <count>" bằng use_count()
    • Tạo một weak_ptr từ một trong các con trỏ chia sẻ
    • Dùng lock() để truy cập tài liệu thông qua con trỏ yếu và in ra "Weak access: <title>"

Nhớ thêm <memory> để dùng con trỏ thông minh. Dùng std::make_unique và std::make_shared để tạo con trỏ thông minh. Các thông báo từ hàm hủy sẽ giúp bạn biết khi nào mỗi tài liệu được tự động dọn dẹp vào cuối chương trình.

Thêm tệp tiêu đề vào main.cpp bằng #include "Document.h".

Tự làm thử

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: Tạo một unique_ptr trỏ đến Document với inputTitle
    // bằng std::make_unique

    // TODO: In ra "Unique owner: <title>"

    // TODO: Chuyển quyền sở hữu sang một unique_ptr khác bằng std::move

    // TODO: In ra "Ownership transferred"

    // TODO: Tạo một shared_ptr trỏ đến Document mới có tiêu đề "SharedDoc"
    // bằng std::make_shared

    // TODO: Tạo một shared_ptr thứ hai trỏ đến cùng tài liệu

    // TODO: In ra "Shared owners: <count>" bằng use_count()

    // TODO: Tạo một weak_ptr từ một trong các shared_ptr

    // TODO: Dùng lock() để truy cập tài liệu qua weak_ptr
    // và in ra "Weak access: <title>"

    return 0;
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C++ online