2015-02-07 17 views
11

Bây giờ, tôi biết các vấn đề chung với unique_ptr <> và chuyển tiếp các khai báo như trong Forward declaration with unique_ptr?.Không thể sử dụng tiêu chuẩn :: unique_ptr <T> với T là khai báo chuyển tiếp

Hãy xem xét ba tập tin:

A.h

#include <memory> 
#include <vector> 

class B; 

class A 
{ 
public: 
    ~A(); 

private: 
    std::unique_ptr<B> m_tilesets; 
}; 

C.cpp

#include "A.h" 

class B { 

}; 

A::~A() { 

} 

main.cpp

#include <memory> 

#include "A.h" 

int main() { 
    std::unique_ptr<A> m_result(new A()); 
} 

Phát hành g++ -std=c++11 main.cpp C.cpp sản lượng các lỗi sau:

In file included from /usr/include/c++/4.8/memory:81:0, 
       from main.cpp:1: 
/usr/include/c++/4.8/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]’: 
/usr/include/c++/4.8/bits/unique_ptr.h:184:16: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = B; _Dp = std::default_delete<B>]’ 
A.h:6:7: required from here 
/usr/include/c++/4.8/bits/unique_ptr.h:65:22: error: invalid application of ‘sizeof’ to incomplete type ‘B’ 
    static_assert(sizeof(_Tp)>0, 

Đó là sự thật, B là loại không đầy đủ trong dòng 6 của A.h - nhưng đó không phải là nơi hủy diệt của A! g ++ dường như tạo ra một destructor cho A mặc dù tôi đang cung cấp một. A destructor là trong C.cpp dòng 7 và có B là một loại được xác định hoàn hảo. Tại sao tôi nhận được lỗi này?

Trả lời

12

Bạn cũng cần phải đặt constructor Một trong C.cpp:

A.h

#include <memory> 
#include <vector> 

class B; 

class A { 
public: 
    A(); 
    ~A(); 

private: 
    std::unique_ptr<B> m_tilesets; 
}; 

C.cpp

#include "A.h" 

class B { 

}; 

A::~A() { 

} 

A::A() { 

} 

Xem this answer. Các nhà xây dựng cần truy cập vào loại hoàn chỉnh là tốt. Điều này là để nó có thể gọi deleter nếu một ngoại lệ được ném trong khi xây dựng.

+1

Cùng xảy ra btw cho các nhà xây dựng di chuyển, nếu nó không được ngầm định nghĩa là xóa vì destructor rõ ràng-tuyên bố. (Và bản sao ctor được định nghĩa là bị xóa cũng vì không thể sao chép 'unique_ptr'.) – dyp

6

Hàm thành viên đặc biệt được xác định ngầm định là nội tuyến, dẫn đến sự cố với các loại không đầy đủ. Với tư cách là link từ các chương trình Chris's answer, tất cả các nhà xây dựng không ủy nhiệm có khả năng có thể gọi trình phá hủy. Điều này bao gồm bản sao (xóa trong trường hợp này) và di chuyển các nhà xây dựng là tốt. Vì vậy, khi bạn đang đối phó với các thành viên không tĩnh liên quan đến các loại không đầy đủ, rõ ràng mặc định các định nghĩa trong tệp nguồn, do đó đảm bảo rằng chúng không được xác định nội tuyến.

Trong tiêu đề:

A(); 
~A(); 
A(const A&); 
A(A&&); 

Trong source:

A::A() = default; 
A::~A() = default; 
A::A(const A&) = default; 
A::A(A&&) = default; 
+0

Bạn có hai lỗi chính tả trong tệp nguồn (thiếu' = '). Ngoài ra, ctor sao chép không thể được mặc định trong trường hợp này. – dyp

+0

Tôi đã đề cập đến thực tế về ctor sao chép trong câu trả lời. Sửa lỗi đánh máy. Cảm ơn! – Pradhan

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