2010-08-31 38 views
12

Tôi vừa mới bắt đầu lập trình bằng C++ và tôi đã cố gắng tạo 2 lớp mà một lớp sẽ chứa lớp kia.Tên lớp không đặt tên loại trong C++

file A.h:

#ifndef _A_h 
#define _A_h 

class A{ 
    public: 
     A(int id); 
    private: 
     int _id; 
     B _b; // HERE I GET A COMPILATION ERROR: B does not name a type 
}; 

#endif 

file A.cpp:

#include "A.h" 
#include "B.h" 
#include <cstdio> 

A::A(int id): _id(id), _b(){ 
    printf("hello\n the id is: %d\n", _id); 
} 

file B.h:

#ifndef _B_h 
#define _B_h 

class B{ 
    public: 
     B(); 
}; 
#endif 

file B.cpp:

#include "B.h" 
#include <cstdio> 

B::B(){ 
    printf("this is hello from B\n"); 
} 

tôi lần đầu tiên biên dịch lớp B và sau đó là Một lớp học, nhưng sau đó tôi nhận được thông báo lỗi:

A.h:9: error: ‘B’ does not name a type

Làm thế nào để khắc phục vấn đề này?

+0

@Georg tại sao bạn đặt mọi thứ trong một đoạn mã? Chúng là các tệp khác nhau. –

+0

@Amir: Nó trông bị hỏng trước khi tôi nhấp vào * chỉnh sửa * và tôi đã vắng mặt :) –

+0

Bạn có thể chấp nhận một trong các câu trả lời mà bạn thấy hữu ích nhất bằng cách nhấp vào dấu tích bên cạnh câu trả lời. Điều này sẽ hữu ích cho những người khác sẽ gặp vấn đề tương tự. – Naveen

Trả lời

25

Bộ tiền xử lý chèn nội dung của các tệp A.hB.h chính xác nơi xảy ra tuyên bố include (đây thực sự chỉ là sao chép/dán). Khi trình biên dịch phân tích cú pháp A.cpp, trình tìm kiếm khai báo lớp A trước khi nó biết về lớp B. Điều này gây ra lỗi mà bạn nhìn thấy. Có hai cách để giải quyết vấn đề này:

  1. trong A.h. Nó thường là một ý tưởng tốt để bao gồm các tập tin tiêu đề trong các tập tin mà họ đang cần. Nếu bạn dựa vào sự bao gồm gián tiếp mặc dù một tiêu đề khác, hoặc một thứ tự đặc biệt bao gồm trong đơn vị biên dịch (cpp-file), điều này sẽ chỉ gây nhầm lẫn cho bạn và những người khác khi dự án trở nên lớn hơn.
  2. Nếu bạn sử dụng biến thành viên loại B trong lớp A, trình biên dịch cần biết khai báo chính xác và đầy đủ B, vì cần tạo bố cục bộ nhớ cho A. Mặt khác, nếu bạn đang sử dụng một con trỏ hoặc tham chiếu đến B, thì một khai báo chuyển tiếp sẽ đủ, bởi vì bộ nhớ mà trình biên dịch cần phải dự trữ cho một con trỏ hoặc tham chiếu độc lập với định nghĩa lớp. Điều này sẽ giống như sau:

    class B; // forward declaration   
    class A { 
    public: 
        A(int id); 
    private: 
        int _id; 
        B & _b; 
    }; 
    

    Điều này rất hữu ích để tránh phụ thuộc vòng tròn giữa các tiêu đề.

Tôi hy vọng điều này sẽ hữu ích.

2

Bao gồm "B.h" trong "A.h". Điều đó mang đến tuyên bố 'B' cho trình biên dịch trong khi biên dịch 'A'.

Dấu đầu tiên được giữ trong trường hợp OP.

$ 3.4.1/7 -

"A name used in the definition of a class X outside of a member function body or nested class definition27) shall be declared in one of the following ways:

before its use in class X or be a member of a base class of X (10.2), or

— if X is a nested class of class Y (9.7), before the definition of X in Y, or shall be a member of a base class of Y (this lookup applies in turn to Y’s enclosing classes, starting with the innermost enclosing class),28) or

— if X is a local class (9.8) or is a nested class of a local class, before the definition of class X in a block enclosing the definition of class X, or

— if X is a member of namespace N, or is a nested class of a class that is a member of N, or is a local class or a nested class within a local class of a function that is a member of N, before the definition of class X in namespace N or in one of N’s enclosing namespaces."

3

Bạn phải đầu tiên bao gồm B.h từ A.h. B b; không có ý nghĩa cho đến khi bạn đã bao gồm B.h.

2

Vấn đề là bạn cần phải bao gồm B.h trong tệp A.h của mình. Vấn đề là trong định nghĩa của A, trình biên dịch vẫn không biết những gì B là. Bạn nên bao gồm tất cả các định nghĩa của tất cả các loại bạn đang sử dụng.

1

khi bạn xác định các lớp A, trong Ah, bạn explicitely nói rằng lớp có thành viên B.

Bạn PHẢI bao gồm "Bh" trong "Ah"

1

Không phải bạn bỏ lỡ # bao gồm "Bh" trong Ah?

2
error 'Class' does not name a type 

Chỉ trong trường hợp một người nào đó làm điều ngu ngốc cùng tôi đã làm ... tôi đã tạo ra một chương trình thử nghiệm nhỏ từ đầu và tôi đã gõ Lớp thay vì lớp (với C nhỏ). Tôi đã không nhận được bất kỳ thông báo của các dấu ngoặc kép trong thông báo lỗi và đã dành một chút quá lâu không hiểu vấn đề của tôi.

Tìm kiếm của tôi cho một giải pháp đưa tôi đến đây vì vậy tôi đoán điều tương tự cũng có thể xảy ra với người khác.

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