不科学啊!定义class private 变量,class中一个方法做初始化,另一个方法调用时为null

客观,麻烦帮忙解释。伪代码如下:

class MyClass{
private:
type* a; //就是这个变量

public:
void Init(); //对a做初始化
void Use() //使用a变量,为null
}

情况补充:

  1. Init方法是肯定触发了(打印了log)
  2. Use的方法调用是在类(CCLayer)的通过定时器(CCDirector::sharedDirector…)触发的。

估计是init的时候的问题。
可能是你以一个init函数里面的局部变量,初始化a这个变量的。a是个指针,运行完init函数。局部变量被清除。
a指向就空了。
在use的时候,当然得到的也是空的。

虽然看代码我能知道,不看代码我还真猜不出来 :2:

把init 和 Use 函数定义发出来看看。

亲爱的 shujun.qiao ,代码截图如下

#ifndef HELLOWORLD_SCENE_H
#define HELLOWORLD_SCENE_H

#include “cocos2d.h”
#include “pomelo.h”
#include “cocos-ext.h”
//#include “CocosGUI.h”
#include “DILayer.h”
using namespace cocos2d;
using namespace cocos2d::extension;

class LoginScene : public DILayer
{
private:
pc_client_t* pomelo_client;
const char* sessionID;

public:
// Here’s a difference. Method ‘init’ in cocos2d-x returns bool, instead of returning ‘id’ in cocos2d-iphone
virtual bool init();
virtual void onEnter();
// there’s no ‘id’ in cpp, so we recommend returning the class instance pointer
static cocos2d::CCScene* scene();

// a selector callback
void menuCloseCallback(CCObject* pSender);

static void requstLoginCallback(pc_request_t *req, int status, json_t *resp);
void login(CCObject* obj,TouchEventType tType);
void intoLoddy();

// implement the “static node()” method manually
CREATE_FUNC(LoginScene);

};

#endif // HELLOWORLD_SCENE_H

LoginScene.cpp代码如下

#include “LoginScene.h”
#include “GameLobbyScene.h”
#include “SimpleAudioEngine.h”

using namespace cocos2d;
using namespace cocos2d::extension;

//判断是否登录
static bool isLogin = false;

CCScene* LoginScene::scene()
{
// ‘scene’ is an autorelease object
CCScene *scene = CCScene::create();

// 'layer' is an autorelease object
LoginScene *layer = LoginScene::create();

// add layer as a child to scene
scene->addChild(layer);

// return the scene
return scene;

}

UITextField* txtNickname;

// on “init” you need to initialize your instance
bool LoginScene::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
//static const char* musicName = MUSIC_BG;
//CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic(musicName, true);

UILayer *m_pUiLayer = UILayer::create();
m_pUiLayer->scheduleUpdate();

UIWidget *m_pWidget = dynamic_cast<Layout*>(CCUIHELPER->createWidgetFromJsonFile("Ditix_1.json"));
m_pUiLayer->addWidget(m_pWidget);
UIButton *btnStart = dynamic_cast<UIButton*>(m_pUiLayer->getWidgetByName("btnStart"));
txtNickname = dynamic_cast<UITextField*>(m_pUiLayer->getWidgetByName("txtNickname"));
btnStart->addPushDownEvent(btnStart, coco_pushselector(LoginScene::login));

this->addChild(m_pUiLayer);
return true;

}

void LoginScene::onEnter()
{
CCLayer::onEnter();
CCLOG(“Login onEnter”);
CCDirector::sharedDirector()->getScheduler()->scheduleSelector(schedule_selector(LoginScene::intoLoddy), this, 0, false);
}

void LoginScene::intoLoddy(){
if(isLogin){
isLogin = false;
CCLOG(“isLogin is true”);
CCDirector::sharedDirector()->getScheduler()->pauseTarget(this);
CCScene *lobbyScene = CCScene::create();
GameLobby *layer = new GameLobby();
layer->setClient(pomelo_client);
CCLog(" request client.state:%i", pomelo_client->state);

    layer->setSessionID(sessionID);
    layer->init();
    lobbyScene->addChild(layer);
    CCDirector::sharedDirector()->replaceScene(lobbyScene);
}

}

// send a request
void LoginScene::login(CCObject* obj,TouchEventType tType) {
sessionID = txtNickname->getStringValue();

const char *ip = DI_SERVER_ENTRY_IP;
int port = DI_SERVER_ENTRY_PORT;
pomelo_client = pc_client_new();
CCLog(" login  client.state:%i", pomelo_client->state);

struct sockaddr_in address;
memset(&address, 0, sizeof(struct sockaddr_in));
address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = inet_addr(ip);

// try to connect to server.
if(pc_client_connect(pomelo_client, &address)) {
    CCLOG("fail to connect server.\n");
    pc_client_destroy(pomelo_client);
    return ;
}
const char *route = "connector.entryHandler.login";
json_t *msg = json_object();
json_t *str = json_string(sessionID);
json_object_set(msg, "uid", str);
// decref for json object
json_decref(str);

pc_request_t *request = pc_request_new();
void (*on_requst_login_cb)(pc_request_t *req, int status, json_t *resp) = &LoginScene::requstLoginCallback;
pc_request(pomelo_client, request, route, msg, on_requst_login_cb);
CCLog(" login  client.state:%i", pomelo_client->state);
// main thread has nothing to do and wait until child thread return.
//pc_client_join(client);

// release the client
//pc_client_destroy(client);
//pc_client_stop(pc_client);

}

void LoginScene::requstLoginCallback(pc_request_t *req, int status, json_t *resp){
if(status == -1) {
CCLOG(“Fail to send request to server.\n”);
} else if(status == 0) {
char *json_str = json_dumps(resp, 0);
CCLOG(“server response: %s \n”, json_str);
isLogin = true;
CCLog(" login client.state:%i", req->client->state);
//pc_request_destroy(req);
//pc_client_t *pc_client = req->client;
//pc_client_stop(pc_client);
}
}

void LoginScene::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
CCMessageBox(“You pressed the close button. Windows Store Apps do not implement a close button.”,“Alert”);
#else
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
#endif
}

pomelo_client = pc_client_new(); //这个才是关键的初始化
:12:

我模拟了一下,结果必须是null的。(当然咱们new_client函数里面的不太一样就是了)

init(){
    ...
    pomelo_client = new_client();
    CCLOG("pomelo_client: %x, %d.", pomelo_client, *pomelo_client);
    setClient(pomelo_client);
}

int* QTest::new_client()
{
    int a = 132;
    return &a;
}
void QTest::setClient(int* client)
{
    CCLOG("client: %x, %d.", client, *client);
}

版主大人,为什么会出现这种情况呢?不理解啊。。。明明一开始已经初始化了(pomelo_client = pc_client_new();),为什么之后访问的时候丢失了?

有什么办法能解决吗?

pc_client_new(); //这个函数是怎么实现的?
你看看里面的实现。
像这种:

int* QTest::new_client()
{
    int a = 132;
    return &a;
}
```

肯定是会报错的。
因为里面是一个局部变量。
---
解决的方法,就是这里不要用局部变量。但没看到你的 pc_client_new()这个函数是怎么实现的。不好下结论。

是不是你的LoginScene::login 没在 LoginScene::intoLoddy()之前运行呢