2010-09-04 44 views
13

Tôi cố gắng để viết một chức năng mà sẽ kiểm tra nếu một đối tượng tồn tại:làm thế nào tôi có thể kiểm tra nếu một đối tượng tồn tại trong C++

bool UnloadingBay::isEmpty() { 
    bool isEmpty = true; 
    if(this->unloadingShip != NULL) { 
     isEmpty = false; 
    } 
    return isEmpty; 
} 

Tôi khá mới để C++ và không chắc chắn nếu nền Java của tôi là khó hiểu một cái gì đó, nhưng trình biên dịch đưa ra một lỗi:

UnloadingBay.cpp:36: error: no match for ‘operator!=’ in ‘((UnloadingBay*)this)->UnloadingBay::unloadingShip != 0’ 

Tôi dường như không thể hiểu tại sao nó không hoạt động.

Đây là tuyên bố cho lớp UnloadingBay:

class UnloadingBay { 

    private: 
     Ship unloadingShip; 

    public: 
     UnloadingBay(); 
     ~UnloadingBay(); 

     void unloadContainer(Container container); 
     void loadContainer(Container container); 
     void dockShip(Ship ship); 
     void undockShip(Ship ship); 
     bool isEmpty(); 

}; 
+0

Đang dỡ tảiShip một chức năng lớp học? Bạn có thể đăng tuyên bố lớp học của mình không? –

+0

No unloadingShip là một thuộc tính của unLoadingBay, là lớp mà isEmpty là một thành viên –

+4

pharma_joe: Là một mẹo chung: Mọi thứ bạn đã học trong Java? Quên đi. Nó sẽ không giúp bạn trong C++. – greyfade

Trả lời

22

Có vẻ như bạn có thể cần mồi trên khái niệm "biến" trong C++.

Trong C++ mỗi vòng đời của biến được gắn với phạm vi bao gồm của nó. Ví dụ đơn giản nhất của việc này là các biến cục bộ của hàm:

void foo() // foo scope begins 
{ 
    UnloadingShip anUnloadingShip; // constructed with default constructor 

    // do stuff without fear! 
    anUnloadingShip.Unload(); 
} // // foo scope ends, anything associated with it guaranteed to go away 

Trong mã "anUnloadingShip" trên là mặc định được xây dựng khi hàm foo được nhập (tức là phạm vi của nó được nhập vào). Không cần "mới". Khi phạm vi bao trùm biến mất (trong trường hợp này khi thoát foo), trình phá hủy do người dùng định nghĩa của bạn được tự động gọi để làm sạch UnloadingShip. Bộ nhớ liên quan được tự động dọn dẹp.

Khi phạm vi bao trùm là một ++ lớp C (có nghĩa là để nói một biến thành viên):

class UnloadingBay 
{ 
    int foo; 
    UnloadingShip unloadingShip; 
}; 

cuộc đời gắn liền với các thể hiện của lớp, vì vậy khi chức năng của chúng tôi tạo ra một "UnloadingBay"

void bar2() 
{ 
    UnloadingBay aBay; /*no new required, default constructor called, 
         which calls UnloadingShip's constructor for 
         it's member unloadingShip*/ 

    // do stuff! 
} /*destructor fires, which in turn trigger's member's destructors*/ 

các thành viên của aBay được xây dựng và sống miễn là "aBay" sống.

Tất cả điều này được tìm ra tại thời gian biên dịch. Không có tham chiếu thời gian chạy nào ngăn ngừa sự phá hủy.Không có cân nhắc nào được thực hiện cho bất kỳ điều gì khác có thể là refer to hoặc point to biến đó. Trình biên dịch phân tích các hàm chúng tôi đã viết để xác định phạm vi, và do đó toàn thời gian, của các biến. Trình biên dịch sẽ thấy phạm vi của một biến kết thúc và bất cứ thứ gì cần thiết để làm sạch biến đó sẽ được chèn vào lúc biên dịch.

"mới", "NULL", (đừng quên "xóa") trong C++ đi vào chơi với con trỏ. Con trỏ là một loại biến chứa địa chỉ bộ nhớ của một số đối tượng. Các lập trình viên sử dụng giá trị "NULL" để chỉ ra rằng một con trỏ không giữ một địa chỉ (nghĩa là nó không trỏ đến bất kỳ thứ gì). Nếu bạn không sử dụng con trỏ, bạn không cần phải suy nghĩ về NULL.

Cho đến khi bạn đã nắm vững cách các biến trong C++ đi vào và ra khỏi phạm vi, hãy tránh các con trỏ. Đó là một chủ đề khác hoàn toàn.

Chúc may mắn!

+0

Xin cảm ơn rất nhiều, tôi đánh giá cao nó rất nhiều. Con trỏ đang cho tôi một chút rắc rối để hiểu, nhưng tôi đến đó. Chúc mừng –

+0

Tôi thích phần "đảm bảo" :-) Đặc biệt nếu một số anh chàng quyết định ném ngoại lệ trong destructor! –

+0

@Vlad, khi bạn ném vào một destructor, chương trình của bạn được đảm bảo để biến mất như vậy hoặc là cách biến đi :) –

1

Tôi giả định unloadingShip là một đối tượng và không phải là một con trỏ nên giá trị không bao giờ có thể là NULL.

tức là.

SomeClass unloadingShip

so

SomeClass * unloadingShip

+0

Vâng, đó là một đối tượng. Làm thế nào tôi có thể kiểm tra xem unloadingShip có được khởi tạo hay không? –

+3

Nếu UnloadingBay được khởi tạo, thì đối tượng unloadingShip của nó cũng được khởi tạo (ngay cả khi bạn đang ở trong hàm tạo UnloadingBay). – EboMike

+0

nếu "this" (còn gọi là đối tượng UnloadingBay) được khởi tạo, unloadingShip cũng sẽ tự động được khởi tạo, bởi vì unloadingShip là một phần của đối tượng UnloadingBay. tức là đối tượng UnloadingBay và đối tượng UnloadingShip đều là một phần của cùng một bộ nhớ, nếu bạn muốn. Nó không giống như Java, nơi mọi đối tượng phải được phân bổ riêng lẻ. –

1

Vâng, bạn không cần phải viết rất nhiều mã để kiểm tra xem một con trỏ là NULL hay không. Phương pháp này có thể đơn giản hơn rất nhiều:

bool UnloadingBay::isEmpty() const { 
    return unloadingShip == NULL; 
} 

Thêm vào đó, nó sẽ được đánh dấu là "const" bởi vì nó không thay đổi trạng thái của đối tượng và có thể được gọi vào trường hợp liên tục là tốt.

Trong trường hợp của bạn, "unloadingShip" là đối tượng của lớp "UnloadingShip" không được cấp động (trừ khi toàn bộ lớp "UnloadingBay" được cấp động). Vì vậy, kiểm tra nếu nó bằng NULL không có ý nghĩa bởi vì nó không phải là một con trỏ.

+0

OK Tôi đã thêm tuyên bố. Cảm ơn! –

1

Đối với việc kiểm tra, nếu một đối tượng tồn tại, bạn có thể xem xét việc đi theo cách này:

tạo ra một con trỏ đến đối tượng của bạn:

someClass *myObj = NULL // Make it null 

và bây giờ nơi bạn vượt qua con trỏ này, bạn có thể kiểm tra:

if(!myObj) // if its set null, it wont pass this condition 
    myObj = new someClass(); 

và sau đó trong trường hợp bạn muốn xóa, bạn có thể làm điều này:

if(myobj) 
{ 
    delete myObj; 
    myObj = NULL; 
} 

vì vậy theo cách này, bạn có thể kiểm soát tốt việc kiểm tra xem đối tượng của bạn có tồn tại hay không trước khi xóa đối tượng hoặc trước khi tạo đối tượng mới.

Hy vọng điều này sẽ hữu ích!

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