STACK.peek函数,有点麻烦,C ++

时间:2011-04-05 23:51:24

标签: c++ class function struct tostring

CARD& STACK::peek()
{
    if(cards.size == 0)
    {
        CARD temp = CARD {-1, -1};
        return temp;
    }
    return cards.back();
}

这是我遇到麻烦的功能。

  • CARD只有structint个变量,名为ranksuit

  • STACK是管理class的{​​{1}},名为std::vector<CARD>

该函数应该将cards返回到堆栈顶部的卡上,或者如果reference为空,则将引用返回到虚拟卡。

首先,我收到一条警告,提示返回对本地变量vector的引用。这有什么问题?这对功能有何影响?我该怎么办呢?

其次,我试图将此函数与我创建的另一个名为temp

的函数一起使用
cardToString

应该使用传递的char* cardToString(CARD& c); 中的ranksuit变量来查找表中的字符串值,将两个字符串连接在一起,并返回指向新字符串。

所以最终结果如下:

CARD

但是这行代码将执行cout<<cardToString(deck.peek())<<"\n"; 函数,然后由于某种原因停止。这让我感到烦恼,因为它刚刚停止,没有错误信息,看起来我没有任何错误。

有人可以帮帮我吗?

编辑:这是cardToString函数

cardToString

我特别希望函数char *cardToString(const CARD& c) { if(c.r >= 13 || c.r < 0 || c.s >= 4 || c.s < 0) { std::cout<<"returned null"; return NULL; } char *buffer = new char[32]; strcpy(buffer, RANKS[c.r]); strcat(buffer, " of "); return strcat(buffer, SUITS[c.s]); } 返回STACK.peek()顶部已存在的CARD的地址。这样做似乎比创建我想要返回的卡片副本更有意义。

2 个答案:

答案 0 :(得分:3)

  

首先,我收到一条警告,提示返回对本地变量temp的引用。这有什么问题?这对功能有何影响?我该怎么办?

顾名思义,局部变量是它所属函数的局部变量,因此它会在函数返回时被销毁;如果你试图返回对它的引用,你将返回对函数返回时将停止存在的东西的引用。

虽然在某些情况下这似乎无论如何都可行,但你只是幸运,因为堆栈没有被覆盖,只是调用其他功能,你会发现它会停止工作。

您有两种选择:首先,您可以按值而不是参考返回CARD;但是,这样做的缺点是不允许调用者使用引用来修改存储在CARD中的vector(这可能是也可能不是)。

另一种方法是在CARD类中存储一个静态虚拟STACK实例,它不会有这些生命周期问题,并且当你没有元素时可以返回vector;但是,你应该找到一种方法来“保护”它的字段,否则一个“愚蠢”的调用者可能会改变你的“单例”虚拟元素的值,搞砸了类的逻辑。可能是在CARD中更改class将封装其字段,如果它是虚拟元素,则会拒绝对它们的写访问。

对于cardToString函数,你可能在对字符串做错了(我几乎肯定你在这种情况下也试图返回一个本地),但是没有看到这个功能很难分辨出来。

顺便说一下,为了避免字符串出现很多问题,我建议您使用char *类而不是std::string类,这样可以消除大部分丑陋和低级内存管理通常char *

此外,我建议您更改cardToString以获取const引用,因为很可能它不需要更改作为参考传递的对象,并且明确标记是一个好习惯这个事实(如果你试图改变这样的引用,编译器会警告你。)


修改 的 只要cardToStringRANKS数组正常,SUITS函数就可以正常工作。 但是,如果你像你写的那样使用了这个函数,那么你就会泄漏内存,因为每次调用cardToString你都会使用new进行分配,而delete永远不会释放{ {1}};因此,每次调用你会丢失32个字节的内存。

如前所述,我的建议只是使用std::string而忘记这些问题;你的功能变得如此简单:

std::string cardToString(const CARD& c)
{
    if(c.r >= 13 || c.r < 0 || c.s >= 4 || c.s < 0)
        return "(invalid card)";

    return std::string(RANKS[c.r]) + " of " + SUITS[c.s];
}

您不再需要担心内存泄漏和内存分配。


对于引用/值事物:如果调用者不需要使用引用来修改存储在向量中的对象,我强烈建议按值传递它。性能损失可以忽略不计:在大多数32位架构上,两个int而不是一个指针意味着8对4字节,在大多数64位机器上有8个字节对8个字节(并且通过指针访问字段也很小)成本)。

这种微观优化应该是您最后关注的问题。您的首要任务是编写正确的工作代码,您应该做的最后一件事是让微优化阻碍这一目标。

然后,如果遇到性能问题,您将对应用程序进行分析,以找出瓶颈所在并优化这些关键点。

答案 1 :(得分:1)

您不能返回对局部变量的引用,因为函数返回时局部变量不再存在。

您需要按值返回,而不是按引用(即CARD STACK::peek() { ... })返回。