2012-12-12 107 views
0

從我所瞭解的情況來說,將整個結構傳遞給函數並且不通過引用的方式這樣做可能會對系統資源徵稅。所以,我想要通過引用來處理它們。我正在創建一個具有以下結構的字符發生器:通過引用將結構數組傳遞給函數的問題

struct Stats{ 
    string name; 
    int level; 
    int HP; 
    int STR; 
    int CON; 
    int DEX; 
    int INT; 
    int WIS; 
    int CHA;}; 

struct Growth{ 
    int HPperlvl; 
    int STRperlvl; 
    int CONperlvl; 
    int DEXperlvl; 
    int INTperlvl; 
    int WISperlvl; 
    int CHAperlvl;}; 

struct Holdstats{ 
    Stats classstats; 
    Growth classgrowth;}; 
const int SIZE = 10; 

Holdstats classlist[SIZE] = { 
    { {"Fighter", 1, 18, 10, 10, 10, 10, 10, 10}, {1,1,1,1,1,1,1} }, 
    { {"Wizard", 1, 10, 10, 10, 10, 10, 10}, {1,1,1,1,1,1,1}}, 
    { {"Rogue", 1, 10, 10, 10, 10, 10, 10}, {1,1,1,1,1,1,1}} 
} //These are just some examples, will be filled later 

Holdstats charlist[SIZE]; //Empty array to store created characters 

我將在程序中使用最簡單的函數來說明我的問題。下面的函數只需顯示傳遞給它的任何結構的信息,無論結構中的哪個位置傳遞給它。該位置在程序中預先定義。我想通過引用傳遞結構和位置。

void dispinfo(const Holdstats &p, int &i) //Should be passed a position and a structure 
{ 
    cout << endl << "\tHere is the Character/Class info you requested: " 
     << "\n\t----------------------------------------------" 
     << "\nName:\t\t" << p[i].classstats.name << endl 
     << "Level:\t\t" << p[i].classstats.level << endl 
     << "Hit Points:\t\t" << p[i].classstats.HP << endl 
     << "Strength:\t\t" << p[i].classstats.STR << endl 
     << "Constitution\t\t" << p[i].classstats.CON << endl 
     << "Dexterity\t\t" << p[i].classstats.DEX << endl 
     << "Intelligence\t\t" << p[i].classstats.INT << endl 
     << "Wisdom\t\t" << p[i].classstats.WIS << endl 
     << "Charisma\t\t" << p[i].classstats.CHA << endl; 

} 

我得到的問題與p[i]有關。我的編譯器告訴我,對於 Holdstats & p - 沒有運算符[]匹配這些操作數。我只會在函數頭中使用一個以前定義的結構數組的名稱(「classlist」或其他),但我希望能夠將任何結構數組傳遞給該函數。

據我所知,我調用先前定義的數組的元素i。但顯然,我做錯了什麼。任何人都可以看到問題嗎?

回答

1

一些想法,試圖幫助。

  • 除非您會在dispinfo()被改變i價值,實在沒有理由按引用傳遞它。通過int並傳遞給int的引用可能是等價的(兩者都比可能多32位),但隨後通過引用訪問該引用(更簡單地)是更多的徵稅,因爲必須對其進行解除引用以獲取該值。
  • 它看起來像你期待一系列Holdstatsstruct s被傳遞到dispinfo()。如果是這種情況,則不需要引用符號,因爲數組總是通過引用傳遞。你應該使用Holdstats p[]而不是const Holdstats &p,並且數組將被傳入(你可以編譯)。要調用dispinfo(),您只需傳遞要打印的數組名稱和索引。

你可能要考慮改變dispinfo()只接收一個Holdstatsstruct,而不是他們的數組。然後這個函數看起來像這樣。

void dispinfo(const Holdstats &p) //Should be passed a structure only 
{ 
    cout << endl << "\tHere is the Character/Class info you requested: " 
     << "\n\t----------------------------------------------" 
     << "\nName:\t\t" << p.classstats.name << endl 
     << "Level:\t\t" << p.classstats.level << endl 
     << "Hit Points:\t\t" << p.classstats.HP << endl 
     << "Strength:\t\t" << p.classstats.STR << endl 
     << "Constitution\t\t" << p.classstats.CON << endl 
     << "Dexterity\t\t" << p.classstats.DEX << endl 
     << "Intelligence\t\t" << p.classstats.INT << endl 
     << "Wisdom\t\t" << p.classstats.WIS << endl 
     << "Charisma\t\t" << p.classstats.CHA << endl; 

} 

然後你打電話給dispinfo()看起來是這樣的。

Holdstats classlist[SIZE] = { [...] }; 
dispinfo(classlist[0]); 
dispinfo(classlist[1]); 
[...] 

這就是你有效地做什麼,通過傳遞數組和索引,像這樣:dispinfo(classlist,0);

+0

非常感謝!我忘記了數組總是通過引用傳遞的。對不起,如果這是一個愚蠢的問題,我正在努力學習這些東西 –

1

那麼,這:

void dispinfo(const Holdstats &p, int &i) 

說,你傳遞給一個參考一個單一的對象。您不能將一個對象取消引用爲一個數組(p[]),以便診斷有意義。

在這種情況下,你可能想要的是:

void dispinfo(const Holdstats *p, int &i) 

,或者:

void dispinfo(const Holdstats p[], int &i) 

由於作爲參數傳遞的數組衰變爲指針的第一要素,他們」大致相同(至少對於一維陣列)。

傳遞對象和到對象,您注意的是經常進行,以避免服用過多的參數傳遞空間(通常在堆疊)的基準之間的差異,是之間的 差:

void dispinfo(const Holdstats p, int &i) 

其將整個對象的副本放到堆棧上,並且:

void dispinfo(const Holdstats &p, int &i) 

哪個沒有。一個引用通常被實現爲一個隱藏的指針,因此在某種意義上,代碼將與傳遞指針非常相似,但C++級別的語義(允許你使用參數)是不同的。將單個對象作爲指針或引用傳遞將導致幾乎相同的代碼,但如果要傳入數組,則需要將其指定爲數組或指針。