как я могу проверить, существует ли объект в C ++

Я пытаюсь написать функцию, которая будет проверять, существует ли объект:

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();

};

person pharma_joe    schedule 04.09.2010    source источник
comment
UnloadingShip - это функция класса? Можете ли вы опубликовать объявление своего класса?   -  person Pablo Santa Cruz    schedule 04.09.2010
comment
No unloadingShip - это атрибут unLoadingBay, который является классом, членом которого является isEmpty.   -  person pharma_joe    schedule 04.09.2010
comment
pharma_joe: В качестве общего совета: все, что вы узнали на Java? Забудь это. Это не поможет вам в C ++.   -  person greyfade    schedule 04.09.2010
comment
И как только вы справитесь с этой проблемой, поймите, что ваша функция isEmpty примерно на четыре строки длиннее, чем должна быть, то есть return this->unloadingShip == NULL;.   -  person Ed S.    schedule 30.01.2012


Ответы (4)


Похоже, вам может понадобиться учебник по концепции «переменной» в 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

В приведенном выше коде "anUnloadingShip" по умолчанию создается, когда вводится функция foo (т.е. вводится ее область действия). Никакого "нового" не требуется. Когда охватывающая область видимости уходит (в данном случае, когда завершается 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.

Все это выясняется во время компиляции. Нет подсчета ссылок во время выполнения, предотвращающего разрушение. Никаких других соображений не делается для чего-либо еще, что могло бы относиться к или укажите эту переменную. Компилятор анализирует написанные нами функции, чтобы определить область действия и, следовательно, время жизни переменных. Компилятор видит, где заканчивается область видимости переменной, и все, что необходимо для очистки этой переменной, будет вставлено во время компиляции.

«new», «NULL» (не забудьте «удалить») в C ++ вступают в игру с указателями. Указатели - это тип переменной, которая содержит адрес в памяти некоторого объекта. Программисты используют значение «NULL», чтобы указать, что указатель не содержит адреса (т. Е. Ни на что не указывает). Если вы не используете указатели, вам не нужно думать о NULL.

Пока вы не освоите, как переменные в C ++ входят в область видимости и выходят за нее, избегайте указателей. Это совсем другая тема.

Удачи!

person Doug T.    schedule 04.09.2010
comment
Привет, большое спасибо, я это очень ценю. Из-за указателей мне трудно понять, но я добираюсь до цели. Ваше здоровье - person pharma_joe; 04.09.2010
comment
Мне нравится гарантированная часть :-) Особенно, если какой-то чувак решает выбросить исключение в деструктор! - person ; 08.09.2010
comment
@Vlad, когда вы добавляете деструктор, ваша программа гарантированно уйдет, так что в любом случае переменная уйдет :) - person Doug T.; 08.09.2010

Я предполагаю, что unloadingShip - это объект, а не указатель, поэтому значение никогда не может быть NULL.

ie.

SomeClass разгрузкаКорабль

против

SomeClass * unloadingShip

person GWW    schedule 04.09.2010
comment
Да, это объект. Как я могу проверить, создан ли unloadingShip или нет? - person pharma_joe; 04.09.2010
comment
Если создается экземпляр UnloadingBay, создается также его объект unloadingShip (даже если вы находитесь в конструкторе UnloadingBay). - person EboMike; 04.09.2010
comment
если это (он же объект UnloadingBay) создается, unloadingShip также будет автоматически создан, потому что unloadingShip является частью объекта UnloadingBay. то есть объект UnloadingBay и объект UnloadingShip являются частью одного и того же блока памяти, если хотите. Это не похоже на Java, где каждый отдельный объект должен быть выделен индивидуально. - person Jeremy Friesner; 04.09.2010
comment
Да, я думаю, у меня проблемы с адаптацией к указателям и ссылкам. Я включил объявление класса для пояснения. - person pharma_joe; 04.09.2010

Что ж, вам не нужно писать так много кода, чтобы проверить, является ли указатель NULL или нет. Метод мог бы быть намного проще:

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

Кроме того, он должен быть помечен как «const», потому что он не изменяет состояние объекта и может вызываться также для константных экземпляров.

В вашем случае unloadingShip - это объект класса UnloadingShip, который не выделяется динамически (кроме случаев, когда весь класс UnloadingBay выделяется динамически). Таким образом, проверка, равняется ли он NULL, не имеет смысла, потому что это не указатель.

person Community    schedule 04.09.2010
comment
ОК, я добавил декларацию. Спасибо! - person pharma_joe; 04.09.2010

Чтобы проверить, существует ли объект, вы можете подумать о следующем:

создать указатель на свой объект:

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;
}

Таким образом, вы можете хорошо контролировать, существует ли ваш объект, перед его удалением или перед созданием нового.

Надеюсь это поможет!

person linuxeasy    schedule 30.01.2012