2013-06-27 68 views
1

我是來自java/python/etc背景的C++的新手,並且在下一學期必須上課之前,我正在嘗試自學面向對象編程。函數完成後類變量重置

我試圖製作一個使用SFML的動畫系統,但是在使用我的一個類變量時遇到了一些麻煩;增加後它會一直保持爲0。我將從代碼開始,並跟隨我正在使用的日誌輸出來幫助弄清楚發生了什麼。

SOLUTION:作爲C++的新手,我是一個笨蛋,在我的getter函數中返回了一個新類的實例;使用[class] & func()...而不是[class] func()解決了這個問題,但現在我有一些重構要做。

碼(頭):

... 

typedef std::vector<Frame> frameVect; // (Frame defined above) 
typedef std::vector<double> dubVect; 

... 

class limbAnim 
{ 
private: 
    int limbNum; 
    int numFrames; 
    int curFrame; 
    frameVect frames; 

public: 
    limbAnim(int limb, int nFrames, frameVect F); 
    <getters/setters> 
    void incCurFrame(); 

    dubVect incrementAnimation(dubVect curPos, double curRot); 
} 

碼(CPP):

... (include vector, ofstream, etc) 

std::ofstream AnimLog("log.log") 

typedef std::vector<Frame> frameVect; // (Frame defined above) 
typedef std::vector<double> dubVect; 

... 

limbAnim::limbAnim(int limb, int nFrames, frameVect F) 
{ 
    limbNum = limb; 
    curFrame = 0; 
    numFrames = nFrames; 
    frames = F; 
} 

void limbAnim::incCurFrame() 
{ 
    curFrame=curFrame+1; 
    if (curFrame >= numFrames) 
    { 
     curFrame = 0; 
     AnimLog << "Greater than." << std::endl; 
    } 
} 

dubVect limbAnim::incrementAnimation(dubVect curPos, double curRot) 
{ 
    AnimLog << limbNum << ", " << numFrames << std::endl; 

    if (numFrames > 0) 
    { 
     AnimLog << curFrame << std::endl; 
     dubVect curStepP = frames[curFrame].getStepPos(); 
     double curStepR = frames[curFrame].getStepRot(); 

     curPos[0] = curPos[0] + curStepP[0]; 
     curPos[1] = curPos[1] + curStepP[1]; 

     curRot = curRot + curStepR; 

     incCurFrame(); 
     AnimLog << "Incremented: " << curFrame << std::endl; 
    } 

    dubVect retV = curPos; 
    retV.push_back(curRot); 
    return retV; 
} 

所以,我的日誌輸出看起來不錯,因爲我有2幀的四肢6 & 8測試,除了那些四肢的curFrame似乎在增加後重置爲0:

... 
5, 0 
6, 2 
0 
Incremented: 1 
7, 0 
8, 2 
0 
Incremented: 1 
9, 0 
... 
5, 0 
6, 2 
0 
Incremented: 1 
7, 0 
8, 2 
0 
Incremented: 1 
9, 0 
...(ad nauseam) 

編輯:調用增量函數的代碼。 (main.cpp中)

// (Outside main loop.) 
Animation walk_anim(12, "assets/anim/walk.dat"); 

// (Inside main loop.) 
for (int i=0; i<12; i++) 
{ 
    dubVect animDat = walk_anim.getLimbFrame(i).incrementAnimation(limbPos[i], curDegs[i]); 
    dubVect newPos = getDVect(animDat[0], animDat[1]); 
    double newRot = animDat[2]; 
    curDegs[i] = newRot; 
    if (curDegs[i] >= 360) 
     curDegs[i] -=360; 
    limbPos[i] = newPos; 
} 

getLimbFrame

Animation::Animation(int lNum, string fName) 
{ 
    numLimbs = lNum; 
    fileName = fName; 

    // Fill up limbVect with correct # of empty frames. 
    for (int i=0; i<numLimbs; i++) 
    { 
     frameVect emptyFVect; 
     limbAnim LA(i, 0, emptyFVect); 
     limbFrames.push_back(LA); 
    } 

    // Boring .dat parsing, populates the 'frames' var of each limbAnim. 
    loadAnim(); 
} 

limbAnim Animation::getLimbFrame(int index) 
{ 
    if (index < numLimbs) 
    { 
     return limbFrames[index]; 
    } 
} 

回答

3

希望你知道,你的職責按值獲取參數,所以他們對東西副本工作。

您小心翼翼地避免顯示真正有趣的代碼部分,您可以撥打incrementAnimation,很可能它跟隨其他函數的模式相同。

我建議閱讀如何通過引用和const引用傳遞對象 - 以及函數參數如何在C++中工作。

+0

但curFrame是不會被傳遞到或退回任何的我在這裏使用的功能,所以應該始終保持實例相一致的類變量,對? – Will

+1

整個*相同的*實例,但我們還沒有證明這個 –

+0

我已經編輯我的帖子來添加調用增量函數的代碼 - 我不認爲它每次迭代都定義新的東西。謝謝您的幫助。 – Will

1

我想你需要用static關鍵字聲明該成員變量,那麼你可以說它是一個類變量,它將爲你的類的每個實例共享。像這樣:

static int curFrame; 

然後,您需要從外部de class初始化它。請記住,聲明與初始化有很大不同。

你可以閱讀一下herehere

+0

我不想讓它儘管是靜態的,因爲有幾個類的實例需要具有單獨的變量值。 – Will

+1

是的,我剛剛意識到,閱讀你對其他答案的評論。我試圖在你的代碼中發現錯誤,但目前爲止我沒有看到任何錯誤 –

+1

@當你在'limbAnim :: incrementAnimation'中調用'incCurFrame();'時,'numFrames'的值是什麼? –