2011-10-10 32 views
7

Tôi có hai lớp, foo và bar. foo bao gồm thanh và chứa một std :: vector của con trỏ để thanh các đối tượng. tại một số thời điểm trong thời gian chạy, thanh phải truy cập vectơ này của con trỏ đến các đối tượng thanh khác. Do đó, foo chứa một phương thức có tên getBarObjects() trả về mảng con trỏ.khai báo chuyển tiếp với vectơ loại lớp - con trỏ tới loại lớp không đầy đủ không được phép

Do đó, tôi chuyển tiếp khai báo foo trong thanh. Tôi obvioulsy cũng phải chuyển tiếp khai báo phương thức tôi đang sử dụng - foo :: getBarObjects(). Vì điều này trả về mảng các con trỏ tới thanh, tôi đi vào một vòng luẩn quẩn.

Tôi không thể chuyển tiếp bao gồm Bar và sau đó chỉ đơn giản là chuyển tiếp bao gồm getBarObjects(), vì điều này dẫn đến "tên loại không đầy đủ không được phép".

foo.h:

#include "bar.h" 
#include <vector> 

class foo { 
    public: 
     foo(); 
     ~foo(); 
     std::vector<bar*> getBarObjects(); 
    private: 
     std::vector<bar*> barObjects; 
} 

bar.h:

class foo; 
std::vector<bar*> foo::getBarObjects();  // error, doesn't know bar at this point 

class bar { 
    public: 
     bar(foo *currentFoo); 
     ~bar(); 
     bool dosth(); 
    private: 
     foo *thisFoo; 
} 

bar.cpp:

#include "bar.h" 

bool bar(foo *currentFoo) { 
    thisFoo = currentFoo; 
} 

bool bar::dosth() { 
    thisFoo->getBarObjects();  // error, pointer to inomplete class type is not allowed 
} 

Nếu tôi chỉ đơn giản bao gồm các cách khác xung quanh, tôi sẽ phải chỉ là cùng một vấn đề trong foo lateron. Bất kỳ đề xuất?

Trả lời

15

Bạn không thể chuyển tiếp thành viên khai báo.

Thay vào đó, bar.cpp nên #include cả hai foo.hbar.h. Đã giải quyết được sự cố.

Nói chung, nếu bạn sử dụng các trình tự:

  • Chuyển tiếp tuyên bố tất cả các loại lớp
  • Xác định tất cả các loại lớp
  • Cơ quan của các thành viên lớp

tất cả mọi thứ sẽ ổn thôi.

+0

Meh, giải pháp đơn giản cho một vấn đề có vẻ lớn. Cảm ơn bạn! – Aerius

1

Bạn quên chuyển tiếp khai báo vectơ trong foo.h. Bạn cũng trả lại giá trị vector theo giá trị từ getBarObjects mà có thể không phải là những gì bạn muốn và tuyên bố về phía trước của hàm thành viên là vô ích.

Đồng thời: Sử dụng bộ phận bảo vệ tiêu đề. Ưu tiên con trỏ thông minh thích hợp cho trường hợp của bạn (std::shared_ptr, unique_ptr) trên con trỏ thô. Xem ra cho const ness.

+0

Tôi đã sử dụng tiêu đề bảo vệ, không phải lo lắng, tôi chỉ để chúng ở đây khi tôi nhập tất cả để tránh nhầm lẫn với tên lớp bổ sung và không có gì. Cảm ơn mặc dù – Aerius

4

Bạn không phải bao gồm foo.h hoặc bar.h với nhau trừ khi bạn đang truy cập nội bộ của một trong hai lớp từ tệp tiêu đề khác. Khai báo các lớp khi cần trong các tệp tiêu đề, sau đó bao gồm cả hai tệp tiêu đề từ tệp nguồn của bạn.

foo.h

#include <vector> 
class bar; 
class foo { 
    public: 
     foo(); 
     ~foo(); 
     std::vector<bar*> getBarObjects(); 
    private: 
     std::vector<bar*> barObjects; 
}; 

bar.h

class foo; 
class bar { 
    public: 
     bar(foo *currentFoo); 
     ~bar(); 
     bool dosth(); 
    private: 
     foo *thisFoo; 
} 

quán bar.cpp

#include "foo.h" 
#include "bar.h" 

bool bar(foo *currentFoo) { 
    thisFoo = currentFoo; 
} 

bool bar::dosth() { 
    thisFoo->getBarObjects(); 
} 
Các vấn đề liên quan