2009-10-30 29 views
14

tôi đang tìm kiếm tại Qt dụ here:Qt: "mới không xóa" có gây ra rò rỉ bộ nhớ với các điều khiển không?

và bên trong các nhà xây dựng, họ có:

Window::Window() 
{ 
    editor = new QTextEdit(); // Memory leak? 
    QPushButton *sendButton = new QPushButton(tr("&Send message")); // Memory leak? 

    connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); 

    QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
    buttonLayout->addStretch(); 
    buttonLayout->addWidget(sendButton); 
    buttonLayout->addStretch(); 

    QVBoxLayout *layout = new QVBoxLayout(this); // Memory leak? 
    layout->addWidget(editor); 
    layout->addLayout(buttonLayout); 

    setWindowTitle(tr("Custom Type Sending")); 
} 

Những dòng với ý kiến ​​

// Memory leak? 

không phải là những rò rỉ bộ nhớ?

Nếu vậy, vì lớp Window không có hàm tạo nên tôi nên tạo tất cả các biến đó (trình soạn thảo đã có) Biến thành viên cửa sổ?

Hoặc..không Qt nội bộ "xóa" các biến thành viên đó khi nó nằm ngoài phạm vi?

Trả lời

25

Không, chức năng addWidget() sẽ giữ quyền sở hữu tiện ích. Sau đó nó sẽ phá hủy các widget mà nó sở hữu.

Ngoài ra bạn có thể đọc here rằng:

Như với QObjects, QWidgets thể được tạo ra với các đối tượng cha mẹ để chỉ quyền sở hữu, đảm bảo rằng các đối tượng được xóa khi họ không còn được sử dụng. Với tiện ích con, các mối quan hệ cha-con này có nghĩa là: ý nghĩa bổ sung: Mỗi tiện ích con được hiển thị trong màn hình khu vực bị phụ huynh của nó chiếm giữ. Điều này có nghĩa là khi bạn xóa tiện ích con cửa sổ , tất cả tiện ích con mà nó chứa cũng sẽ bị xóa.

+0

+1 Tôi đã đoán câu trả lời đã xóa của tôi :) – AraK

7

Nếu có ngoại lệ được ném giữa new và addWidget thì có, có rò rỉ bộ nhớ. Nếu không, kiểm soát cha mẹ sẽ sở hữu bộ nhớ.

QHBoxLayout *buttonLayout = new QHBoxLayout(); // Memory leak? 
//make sure you don't throw here 
buttonLayout->addWidget(sendButton); 
5

Ngoài câu trả lời đúng Klaim của:

tôi sẽ lưu trữ những gợi ý trong một std::auto_ptr, trong khi đó bạn chuyển chúng đến cha mẹ của họ.

std::auto_ptr<QHBoxLayout> buttonLayout(new QHBoxLayout()); 
// make things which could throw... 
layout->addLayout(buttonLayout.release()); 

Bằng cách này bạn chắc chắn không bị rò rỉ.

+0

Thậm chí tốt hơn câu trả lời của riêng tôi –

+0

Sẽ không bị xóa hai lần nếu bạn làm điều này? Một lần bằng auto_ptr, sau đó lại bằng QObject? – James

+2

Thay thế std :: auto_ptr by std :: unique_ptr ... – Klaim

0

Nó sẽ không bị xóa gấp đôi vì cuộc gọi .release().

Lưu ý std :: unique_ptr đang thay thế std :: auto_ptr. Hy vọng rằng QT sẽ hỗ trợ ngữ nghĩa di chuyển sau đó phát hành() sẽ thay vì layout-> addLayout (std :: move (buttonLayout)) và không có cuộc gọi di chuyển, bạn sẽ nhận được một lỗi biên dịch.

+1

shared_ptr của nó thay thế auto_ptr, unique_ptr chỉ dành cho ptrs không được chia sẻ, cho biết nó hoàn hảo cho công việc này vì chúng tôi không muốn chia sẻ nó. –

Các vấn đề liên quan