2014-06-17 99 views
1

我需要協調&問題一個唯一的順序數字標識符(1,2,3 ...等)爲對象從特定祖父對象所產生的實例。C++保持計數時,全局變量是不恰當的

我正在使用Microsoft編譯器創建一個C++ DLL,並且其中所有變量都封裝在對象中;全局變量在這種情況下不是一種選擇,實際上正在設計中。

我試過以下方法來解決問題,並發現它不可能通過前向聲明來訪問另一個對象的成員函數(NB代碼來說明我想要實現的,它不會編譯到期不正確的使用提前聲明的訪問成員函數):

祖父類:

//GrandParent 
class GrandParent 
{ 
public GrandParent(){} 

int addParent() 
{ 
Parent *par = new Parent(this); 
return 0; 
} 

int incrementGrandChildIDNumber() 
{ 
return grandChildIDNumber +=1;//increment 
} 

private: 
int grandChildIdNumber;//keep count. This NEEDS to be encapsulated. Cannot be a 
//global variable as there will be multiple instances of GrandParent each counting 
//and labeling it's own grand children. 
}; 

父類:

//Parent 
class GrandParent;//forward declaration 
class Parent 
{ 
public Parent(GrandParent *ptrToGrandParent): ptr2GP(ptrToGrandParent){} 

addGrandChild() 
{ 
id = ptr2GP->incrementGrandChildIDNumber();//but forward declaration does not 
    //give access to GrandParent member functions, right?? 
GrandChild grndChld = new GrandChild(id); 
return 0; 
} 

private: 
int id; 
GrandParent *ptr2GP; 
}; 

如GrandChild類:

//GrandChild 
class GrandChild 
{ 
public: 
    GrandChild(const int &id):idNumber(id){} 

private: 
int idNumber; 
}; 

我簡單的問題,在現實中每個類是更長的時間,並在自己的頭文件中定義。

我的問題是:如果向前聲明不工作和全局變量沒有在這個項目有什麼其他選項可用來協調發行ID號到孫對象合適嗎?

回答

2

單獨的類定義,並在不同的文件中的聲明和使用靜態變量:

// GrandParent.hh 
#ifndef _GrandParent_ 
#define _GrandParent_ 

class Parent; 

class GrandParent 
{ 
    public: 
    GrandParent(); 

    Parent * addParent(); 

    int incrementGrandChildIDNumber(); 

    private: 
    static int grandChildIdNumber; 
}; 

#endif 


// GrandParent.cpp 
#include "GrandParent.hh" 
#include "Parent.hh" 

int GrandParent::grandChildIdNumber = 0; 

GrandParent::GrandParent() 
{ 
} 

Parent * GrandParent::addParent() 
{ 
    Parent * par = new Parent(this); 
    return par; 
} 

int GrandParent::incrementGrandChildIDNumber() 
{ 
    return grandChildIdNumber++; 
} 

// Parent.hh 
#ifndef _Parent_hh_ 
#define _Parent_hh_ 

class GrandParent;//forward declaration 
class GrandChild; 

class Parent 
{ 
    public: 
    Parent(GrandParent *ptrToGrandParent); 

    GrandChild * addGrandChild(); 

    private: 
    int id; 
    GrandParent * ptr2GP; 
}; 
#endif 

// Parent.cpp 
#include "Parent.hh" 

#include "GrandParent.hh" 
#include "GrandChild.hh" 

Parent::Parent(GrandParent * ptrToGrandParent) : 
    ptr2GP(ptrToGrandParent) 
{ 
} 

GrandChild * Parent::addGrandChild() 
{ 
    id = ptr2GP->incrementGrandChildIDNumber(); 
    GrandChild * grndChld = new GrandChild(id); 
    return grndChld; 
} 


// GrandChild.hh 
#ifndef _GrandChild_hh_ 
#define _GrandChild_hh_ 

class GrandChild 
{ 
    public: 
    GrandChild(int id); 

    private: 
    int idNumber; 
}; 

#endif 

// GrandChild.cpp 
#include "GrandChild.hh" 

GrandChild::GrandChild(int id) : 
    idNumber(id) 
{ 
} 

,並利用它們來自主:

#include "GrandParent.hh" 
#include "Parent.hh" 
#include "GrandChild.hh" 

int main(int argc, char ** argv) 
{ 
    GrandParent grandPa; 

    Parent * parent1 = grandPa.addParent(); 
    Parent * parent2 = grandPa.addParent(); 

    GrandChild * gChild1_1 = parent1->addGrandChild(); 
    GrandChild * gChild1_2 = parent1->addGrandChild(); 

    GrandChild * gChild2_1 = parent2->addGrandChild(); 
    GrandChild * gChild2_2 = parent2->addGrandChild(); 
} 
+0

當在現實中應用時,會有多個GrandParent實例,因此它們都將引用* same * static變量?我對嗎?我需要每位祖父母保持獨特的計數,不包括來自其他祖父母的GrandChildren。 – GoFaster

+0

因此,將'GrandParent :: grandChildIdNumber'更改爲非靜態變量,但不要忘記在GrandParent構造函數上進行初始化。 –

0

有一個具有生成唯一標識符的函數的單例類。 (這可以基於計數器是連續的,或者基於其他任何你喜歡的方案。)

或者,這可以只是在基類返回基於靜態計數器唯一ID的功能。你甚至可以把它放在基類的構造函數中。

+0

如何將一個單身允許祖父母的多個實例的一個保持獨特的GrandChildren計數,還允許Parent對象在創建新的Grandchild時獲得計數增量? – GoFaster

+0

啊哈,你是對的,對不起,我誤解了你的問題;我以爲你想要一個由所有實例共享的單個計數器。在這種情況下,你的代碼很好,只需通過分離類的實現和聲明來編譯即可。基本上,蒂佩佩的答案。 – CaptainCodeman