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。但很明显,我做错了什么。任何人都可以看到问题吗?

4

2 回答 2

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

于 2012-12-12T20:09:41.850 回答
1

一些想法可以尝试并提供帮助。

  • 除非您要更改iwithin的值,否则dispinfo()实际上没有理由通过引用传递它。传递 anint和传递对 an 的引用int可能是等价的(两者都比可能多 32 位),但是int通过引用访问它(通常)更费力,因为必须取消引用才能获得该值。
  • 看起来您希望将Holdstats structs 数组传递给dispinfo(). 如果是这种情况,则不需要引用符号,因为数组总是通过引用传递。您应该使用Holdstats p[]而不是,const Holdstats &p并且该数组会很好地传入(并且您可以编译)。要调用dispinfo()您只需传递数组名称和要打印的索引。

您可能需要考虑更改dispinfo()为只接收一个Holdstats struct而不是一组它们。然后函数看起来像这样。

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);

于 2012-12-12T20:04:25.013 回答