2009-11-30 3 views
0

Хорошо, это странно ... Я думаю. Что я имею в виду с названием является:C++: переменная объекта не может быть оценена, но переменная от ссылки на тот же объект может?

внутри функции действуют() из объекта actionHandler у меня есть:

state->getHumanPieces(); 

Что дает мне нарушение адрес какой-то, по-видимому, «это» не имеет «состояние» переменная инициализируется ... так происходит это actionHandler класс имеет статическую переменную, которая является указателем на экземпляр себя, называемый «обработчик» ... и если я делаю:

handler->state->getHumanPieces(); 

Он работает отлично .. Чтобы сделать это еще понятнее:

Указатель 'handler' указывает на единственный экземпляр actionHandler, существующий во всей программе (singleton pattern). Так что, когда я запускаю эту функцию act() из моего объекта actionHandler, это не позволяет мне получить доступ к переменной «state», НО, если из этого объекта я попытаюсь получить доступ к той же переменной через указатель на один и тот же объект, это нормально? Я не понимаю, что происходит. Я не уверен, если это понятно, попробуйте немного запутать, но я надеюсь, что это понятно ..

Кстати, отладчик VS08 показывает, что я имею в виду:

this: 0x000000 {state=???} 
    handler: someAddress {state= someAddress} 
     handler:... 
     state:... 
state: CXX0030: ERROR: expression cannot be evaluated 

Я надеюсь, что делает его более ясным, что это деревце-структура, которая показывает на маленьком окне, где текущие значения переменных показаны (Autos).

EDIT: я так получаем, что этот указатель имеет нулевое значение, я просто не понимаю, как это может быть пустым .. Я выложу код:

actionHandler.h:

class gameState; 

class actionHandler 
{ 
public: 
     static actionHandler* Instance(){return handler;} 
    void act(int,int); 
private: 
    actionHandler(); 
    static actionHandler* handler; 
    gameState *state; 
}; 

actionHandler.cpp:

actionHandler* actionHandler::handler = new actionHandler(); 

actionHandler::actionHandler() 
{ 
     state = gameState::Instance(); 
} 
void actionHandler::act(int x, int y) 
{ 
    state->getHumanPieces(); 
} 

теперь, в gameState.hi имеют сходную структуру (Singleton) и actionHandler * частный Var, который получает инициализируется в:

gameState::gameState() 
{ 
    handler = actionHandler::Instance(); 
} 

а также функция getHandler(), которая возвращает обработчик. Это все должны получить инициализирован в main.cpp:

gameState *currState = gameState::Instance(); 
actionHandler *handler = currState->getHandler(); 

, а затем используется:

handler->act(event->button.x,event->button.y); 

main.cpp написана в простом стиле .c, без заголовка, так что да, я полагаю, функция вызова обработчика статична ... однако я также делаю вызовы указателя gameState *, который предположительно работает точно так же, как actionHandler * one. Надеюсь, это сделает его более понятным.

+0

Не могли бы вы показать нам код, который ведет к действию()? Кажется вероятным, что вам удалось заставить act() работать без того, чтобы неявный этот параметр был установлен так, чтобы указывать на действительный экземпляр объекта (this = NULL, это не хорошо). –

+0

ваш указатель NULL, из-за которого он падает. Просто сомневается, что act() вызывается другим статическим объектом? – Naveen

ответ

1

Похож на случай возникновения фиаско порядка статической инициализации here. Ваши конструкторы статических объектов зависят друг от друга круговым образом, что очень странно.

+0

Thansk для этого я исправил это, сделав каждый класс хранения фактическим объектом самого себя, а не указателем на объект. Не уверен, что это то, что связывает мне ссылка, но это определенно помогло мне прийти к выводу. Хотя я до сих пор не понимаю, почему это работает, а наоборот - нет ... если бы вы могли это объяснить, меня бы оценили. – Zepee

+0

Это мой * guess *, я не уверен, что это полностью так: Поскольку в обоих конструкторах вы вызываете getInstance(), в зависимости от порядка инициализации блоков компиляции cpp, один из указателей будет NULL (поскольку инициализация еще не состоялась). Какой указатель становится NULL, очень сложно предсказать. Вероятно, вы можете задать другой вопрос по этому вопросу, и люди, у которых есть больше знаний по этому вопросу, могут помочь. – Naveen

0

Убедитесь, что объект actionHandler, вызываемый вами act(), инициализирован. Мне кажется, что act() получает вызов по указателю null.

1

Ваш this указатель - null.

Нечто подобное происходит:

actionHandler* actObj = 0; 
actObj->act(); // ERROR access violation 
0

ли ваш actionHandler() или акт() статические методы?

Потому что если это так, совершенно нормально, что ваш указатель равен NULL, потому что статические методы не вызываются из определенного экземпляра объекта.

Например, возьмем объект, который выглядит следующим образом:

class CThing 
{ 
public: 
    static void actionHandler(); 
    void act(); 
protected: 
    static CThing* handler; 
    CState state; 
} 

Если указатель функции на CThing :: actionHandler() передается класс третьей стороны, чтобы получить уведомление о чем-то, когда этот класс вызовов метод CThing :: actionHandler(), чтобы уведомить вас (вызывая: CThing::actionHandler();, а не ptrThing->actionHandler(), как если бы метод actionHandler не был статическим), вы не сможете получить доступ к этому указателю или переменной состояния изнутри actionHandler (или любые последующие вызовы, сделанные из actionHandler), потому что этого указателя нет, нет текущего объекта.

Именно поэтому при использовании handler->state->getHumanPieces() он работает, потому что теперь вы на самом деле ссылаетесь на экземпляр класса CThing (обработчик), а не на определение самого класса.

Надеюсь, я был достаточно ясен. Если нет, не стесняйтесь задавать вопросы.

Смежные вопросы