2012-12-12 108 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++级别的语义(允许你使用参数)是不同的。将单个对象作为指针或引用传递将导致几乎相同的代码,但如果要传入数组,则需要将其指定为数组或指针。