CARD& STACK::peek()
{
if(cards.size == 0)
{
CARD temp = CARD {-1, -1};
return temp;
}
return cards.back();
}
这是我遇到问题的功能。
CARD
只是一个struct
有两个int
变量,称为rank
和suit
.STACK
是class
管理std::vector<CARD>
, 即称为cards
.
该函数应该返回一个 reference
到堆栈顶部的卡片,或者如果 vector
返回对虚拟卡片的引用是空的。
首先,我收到一条警告,指出对局部变量的引用 temp
被退回。这有什么问题?这将如何影响功能?我该怎么办?
其次,我尝试将此函数与我创建的另一个函数 cardToString
结合使用
char* cardToString(CARD& c);
它应该使用 rank
和 suit
传递的变量 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
的地址已经存在于 STACK
的顶部.这样做似乎比创建我要退回的卡片的拷贝更有意义。
最佳答案
First of all, I get a warning that says a reference to a local variable
temp
is returned. What is wrong with that? How will that effect the function? What do i do about it?
顾名思义,局部变量是它所属函数的局部变量,因此在函数返回时被销毁;如果您尝试返回对它的引用,您将返回对在函数返回的那一刻将不复存在的东西的引用。
虽然在某些情况下这似乎仍然有效,但你只是幸运,因为堆栈没有被覆盖,只要调用一些其他函数,你就会发现它会停止工作。
您有两个选择:首先,您可以通过值而不是引用返回CARD
;然而,这样做的缺点是不允许调用者使用引用来修改存储在 vector
中的 CARD
(这可能是理想的,也可能不是理想的)。
另一种方法是在 STACK
类中存储一个静态虚拟 CARD
实例,它不会有这些生命周期问题,并且可以在您不这样做时返回'在 vector
中有元素;但是,您应该找到一种方法来“保护”它的字段,否则“愚蠢”的调用者可能会更改您的“单例”虚拟元素的值,从而搞砸类的逻辑。一种可能性是更改 class
中的 CARD
,它将封装其字段,如果它是虚拟元素,将拒绝对它们的写访问。
至于 cardToString
函数,您可能对字符串做错了什么(而且我几乎可以肯定在这种情况下您也试图返回本地),但没有看到很难说出函数的主体是什么。
顺便说一句,为了避免字符串的许多问题,我建议您使用 std::string
类代替 char *
,它消除了大部分通常的 char *
的丑陋和低级内存管理。
此外,我建议您更改 cardToString
以采用 const
引用,因为它很可能不需要更改作为引用传递的对象,并且清楚地标记这一事实是很好的做法(如果您尝试更改此类引用,编译器会警告您)。
编辑
cardToString
函数应该可以正常工作,只要 RANKS
和 SUITS
数组正常。 但是,如果你像你写的那样使用那个函数,你就会泄漏内存,因为每次调用 cardToString
你都会用 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];
}
而且您无需再担心内存泄漏和内存分配问题。
对于引用/值的事情:如果调用者不需要使用引用来修改存储在 vector 中的对象,我强烈建议按值传递它。性能损失可以忽略不计:两个 int
而不是一个指针意味着在大多数 32 位架构上是 8 字节对 4 字节,在大多数 64 位机器上是 8 字节对 8 字节(并且还通过指针访问字段成本很小)。
这种微优化应该是您最后关心的问题。您的首要任务是编写正确的和有效的代码,您最不应该做的就是让微优化妨碍这一目标。
然后,如果您遇到性能问题,您将分析您的应用程序以找出瓶颈所在并优化这些关键点。
关于c++ - STACK.peek 函数,遇到一些问题,C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5559970/