繁体   English   中英

STACK.peek函数,遇到麻烦,C ++

[英]STACK.peek function, having some trouble, C++

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

这是我遇到的功能。

  • CARD只是具有两个int变量的struct ,称为ranksuit

  • STACK是一个class管理的std::vector<CARD>即称为cards

该函数应该返回reference到卡上的堆栈的顶部,或者所述参考返回到虚拟卡,如果vector是空的。

首先,我得到一条警告,提示返回对局部变量temp的引用。 怎么了 这将如何影响功能? 我该怎么办?

其次,我尝试将此函数与我创建的另一个函数cardToString

char* cardToString(CARD& c);

应该使用传递的CARDranksuit变量来查找表中的字符串值,将两个字符串连接在一起,并返回指向新字符串的指针。

因此最终结果如下所示:

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()返回STACK顶部已经存在的CARD地址。 这样做似乎比创建我要退还的卡的副本更有意义。

首先,我得到一条警告,提示返回对局部变量temp的引用。 怎么了 这将如何影响功能? 我该怎么办?

顾名思义,局部变量是其所属函数的局部变量,因此在函数返回时会被销毁。 如果您尝试返回对它的引用,则将返回对在函数返回的那一刻将不复存在的内容的引用。

尽管在某些情况下这似乎仍然可以正常工作,但是由于堆栈没有被覆盖,您很幸运,只需调用其他函数,您就会注意到它将停止工作。

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

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

至于cardToString函数,您可能cardToString字符串做错了(在这种情况下,我几乎可以肯定,您也试图返回本地变量),但是如果看不到函数的主体,很难分辨出什么。

顺便说一句,以避免而不是用绳子,我建议你使用的很多问题, char * ,该std::string类,这需要最丑陋的和平时的水平低内存管理之外char *

另外,我建议您将cardToString更改为const引用,因为很可能不需要更改作为引用传递的对象,并且良好的做法是清楚地标记这一事实(如果尝试,编译器会警告您更改此类参考)。


编辑 cardToString函数应该可以正常工作,只要RANKSSUITS数组正常即可。 但是 ,如果您像编写时那样使用该函数,则会cardToString内存,因为对于每次对cardToString调用,您都使用new进行分配,而new永远不会通过delete释放。 因此,每个调用将丢失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个字节(而且通过指针访问字段的开销很小)。

这种微优化应该是您最后关心的问题。 您的头等大事是编写正确有效的代码,最后要做的就是让微优化妨碍实现此目标。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM