如何在C++中检查对象是否存在

14

我正在尝试编写一个函数来检查对象是否存在:

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

我对C++很陌生,不确定我的Java背景是否让我产生了混淆,但编译器报错了:

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

我似乎无法弄清楚为什么它不起作用。

这是类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();

};

卸货(unloadingShip)是一个类函数吗?你能发布一下你的类声明吗? - Pablo Santa Cruz
No unloadingShip是unLoadingBay的一个属性,而unLoadingBay是isEmpty成员所在的类。 - pharma_joe
4
作为一条普遍的提示:你在学习Java时所掌握的所有知识?全都忘掉吧。这些知识对学习C++没有帮助。 - greyfade
一旦你解决了这个问题,你会意识到你的isEmpty函数比它实际需要的多了大约四行代码,也就是说,可以简化为return this->unloadingShip == NULL; - Ed S.
4个回答

21

看起来你可能需要先了解C++中“变量”的概念。

在C ++中,每个变量的生命周期都与其所在的范围相关联。其中一个最简单的例子是函数的局部变量:

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
在上述代码中,当进入函数foo时(即进入其作用域),"anUnloadingShip"会默认构造。不需要使用"new"。当包含的作用域消失时(在这种情况下是foo退出时),将自动调用您定义的析构函数以清除UnloadingShip。相关内存会自动清除。
当包含的作用域是一个C++类(也就是说是一个成员变量)时:
class UnloadingBay
{
   int foo;
   UnloadingShip unloadingShip;
};

生命周期与类的实例绑定,因此当我们的函数创建一个"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*/

"aBay"的成员是在编译时构造并且只要"aBay"存在,它们就会一直存在。

这些都是在编译时确定的。没有运行时的引用计数来防止销毁。没有考虑到任何可能引用指向该变量的其他内容。编译器分析我们编写的函数以确定变量的作用域和生存期。编译器看到变量的作用域结束的地方,并插入编译时需要清理该变量的任何内容。

C++中的"new"、"NULL"(不要忘记"delete")与指针有关。指针是一种保存某个对象的内存地址的变量类型。程序员使用"value NULL"表示指针不持有任何地址(即它不指向任何东西)。如果您没有使用指针,则无需考虑NULL。

在掌握了C++变量如何进出作用域之前,请避免使用指针,这是完全不同的一个话题。

祝你好运!


嘿,非常感谢,我非常感激。指针让我有点难以理解,但我正在努力。干杯! - pharma_joe
我喜欢“保证”的部分 :-) 特别是如果有人决定在析构函数中抛出异常的时候! - user405725
@Vlad,当你加入一个析构函数时,你的程序肯定会消失,所以无论如何变量都会消失 :) - Doug T.

1

其实,判断指针是否为空并不需要写那么多代码。方法可以更简单:

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

此外,它应该被标记为“const”,因为它不修改对象的状态,并且可以在常量实例上调用。
在您的情况下,“unloadingShip”是“UnloadingShip”类的一个对象,它没有动态分配(除非整个“UnloadingBay”类是动态分配的)。因此,检查它是否等于NULL是没有意义的,因为它不是指针。

好的,我已经添加了声明。谢谢! - pharma_joe

1
我假设unloadingShip是一个对象而不是指针,因此其值永远不可能为空。
例如:
SomeClass unloadingShip 与
SomeClass *unloadingShip

是的,它是一个对象。我如何检查unloadingShip是否已经实例化? - pharma_joe
3
如果实例化了UnloadingBay,那么它的unloadingShip对象也会被实例化(即使你还在UnloadingBay构造函数中)。 - EboMike
如果实例化了“this”(即UnloadingBay对象),则unloadingShip也将自动实例化,因为unloadingShip是UnloadingBay对象的一部分。也就是说,UnloadingBay对象和UnloadingShip对象都是同一块内存的一部分。这不像Java,每个对象都必须单独分配。 - Jeremy Friesner
是的,我认为我在适应指针和引用方面遇到了麻烦。我已经包含了类声明以澄清。 - pharma_joe

1

如果要检查一个对象是否存在,可以考虑以下方法:

创建指向您的对象的指针:

someClass *myObj = NULL // Make it null

现在你传递这个指针的地方,你可以进行检查:

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

然后如果你想要删除,你可以这样做:

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

这样,您就可以很好地控制在删除对象或创建新对象之前检查其是否存在。

希望这有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接