[英]STACK.peek function, having some trouble, C++
CARD& STACK::peek()
{
if(cards.size == 0)
{
CARD temp = CARD {-1, -1};
return temp;
}
return cards.back();
}
This is the function I am having trouble with. 这是我遇到的功能。
CARD
is just a struct
with two int
variables, called rank
and suit
. CARD
只是具有两个int
变量的struct
,称为rank
和suit
。
STACK
is a class
that manages an std::vector<CARD>
, that is called cards
. STACK
是一个class
管理的std::vector<CARD>
即称为cards
。
The function is supposed to return a reference
to the card on top of the stack, or return the reference to a dummy card if the vector
is empty. 该函数应该返回
reference
到卡上的堆栈的顶部,或者所述参考返回到虚拟卡,如果vector
是空的。
First of all, I get a warning that says a reference to a local variable temp
is returned. 首先,我得到一条警告,提示返回对局部变量
temp
的引用。 What is wrong with that? 怎么了 How will that effect the function?
这将如何影响功能? What do I do about it?
我该怎么办?
Second, I am trying to use this function with another function I created called cardToString
其次,我尝试将此函数与我创建的另一个函数
cardToString
char* cardToString(CARD& c);
It is supposed to use the rank
and suit
variables in the passed CARD
to look up string values in a table, concatenate the two strings together, and return a pointer to the new string. 应该使用传递的
CARD
的rank
和suit
变量来查找表中的字符串值,将两个字符串连接在一起,并返回指向新字符串的指针。
So the end result looks like: 因此最终结果如下所示:
cout<<cardToString(deck.peek())<<"\n";
but this line of code will execute up to the cardToString
function, then just stop for some reason. 但是这一行代码将执行到
cardToString
函数,然后由于某种原因而停止。 It is annoying the hell out of me because it just stops, there is no error message and there does not look like there is anything wrong to me. 这让我很烦恼,因为它只是停止了,没有错误消息,而且看起来好像没有什么错。
Can somebody help me out? 有人可以帮我吗?
Edit: here is the cardToString
function 编辑:这是
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]);
}
I specifically want the function STACK.peek()
to return the address of the CARD
that already exists on the top of the STACK
. 我特别希望函数
STACK.peek()
返回STACK
顶部已经存在的CARD
地址。 It seems to make more sense to do that than to create a copy of the card that I want to return. 这样做似乎比创建我要退还的卡的副本更有意义。
First of all, I get a warning that says a reference to a local variable
temp
is returned.首先,我得到一条警告,提示返回对局部变量
temp
的引用。 What is wrong with that?怎么了 How will that effect the function?
这将如何影响功能? What do i do about it?
我该怎么办?
A local variable, as it name implies, is local to the function it belongs to, so it's destroyed as the function returns; 顾名思义,局部变量是其所属函数的局部变量,因此在函数返回时会被销毁。 if you try to return a reference to it, you'll return a reference to something that will cease to exist at the very moment the function returns.
如果您尝试返回对它的引用,则将返回对在函数返回的那一刻将不复存在的内容的引用。
Although in some cases this may seem to work anyway, you're just being lucky because the stack hasn't been overwritten, just call some other function and you'll notice it will stop working. 尽管在某些情况下这似乎仍然可以正常工作,但是由于堆栈没有被覆盖,您很幸运,只需调用其他函数,您就会注意到它将停止工作。
You have two choices: first of all, you can return the CARD
by value instead of reference; 您有两种选择:首先,您可以按值而不是引用返回
CARD
。 this, however, has the drawback of not allowing the caller to use the reference to modify the CARD
as is stored in the vector
(this may or may not be desirable). 但是,这样做的缺点是不允许调用者使用引用来修改存储在
vector
的CARD
(这可能是希望的,也可能是不希望的)。
Another approach is to have a static dummy CARD
instance stored in the STACK
class, that won't have these lifetime problems, and that can be returned when you don't have elements in the vector
; 另一种方法是在
STACK
类中存储一个静态虚拟CARD
实例,该实例不会出现这些生存期问题,并且当vector
没有元素时可以将其返回; however, you should find a method to "protect" its field, otherwise a "stupid" caller may change the values of your "singleton" dummy element, screwing up the logic of the class. 但是,您应该找到一种“保护”其字段的方法,否则“愚蠢”的调用者可能会更改“单身”虚拟元素的值,从而弄乱了类的逻辑。 A possibility is to change
CARD
in a class
that will encapsulate its fields, and will deny write access to them if it's the dummy element. 一种可能是在将封装其字段的
class
中更改CARD
,并且如果它是伪元素,则将拒绝对其的写访问。
As for the cardToString
function, you're probably doing something wrong with the strings (and I'm almost sure you're trying to return a local also in this case), but without seeing the body of the function it's difficult to tell what. 至于
cardToString
函数,您可能cardToString
字符串做错了(在这种情况下,我几乎可以肯定,您也试图返回本地变量),但是如果看不到函数的主体,很难分辨出什么。
By the way, to avoid many problems with strings I suggest you to use, instead of char *
, the std::string
class, which takes away most of the ugliness and of the low level memory management of the usual char *
. 顺便说一句,以避免而不是用绳子,我建议你使用的很多问题,
char *
,该std::string
类,这需要最丑陋的和平时的水平低内存管理之外char *
。
Also, I'd suggest you to change cardToString
to take a const
reference, because most probably it doesn't need to change the object passed as reference, and it's good practice to clearly mark this fact (the compiler will warn you if you try to change such reference). 另外,我建议您将
cardToString
更改为const
引用,因为很可能不需要更改作为引用传递的对象,并且良好的做法是清楚地标记这一事实(如果尝试,编译器会警告您更改此类参考)。
Edit The cardToString
function should be working fine, as long as the RANKS
and SUITS
arrays are ok. 编辑
cardToString
函数应该可以正常工作,只要RANKS
和SUITS
数组正常即可。 But , if you used that function like you wrote, you're leaking memory, since for each call to cardToString
you make an allocation with new
that is never freed with delete
; 但是 ,如果您像编写时那样使用该函数,则会
cardToString
内存,因为对于每次对cardToString
调用,您都使用new
进行分配,而new
永远不会通过delete
释放。 thus, you are losing 32 bytes of memory per call. 因此,每个调用将丢失32个字节的内存。
As stated before, my tip is to just use std::string
and forget about these problems; 如前所述,我的技巧是仅使用
std::string
并忽略这些问题; your function becomes as simple as this: 您的函数变得像这样简单:
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];
}
And you don't need to worry about memory leaks and memory allocations anymore. 您无需担心内存泄漏和内存分配。
For the reference/value thing: if the caller do not need to use the reference to modify the object stored in the vector, I strongly suggest passing it by value. 对于引用/值的事情:如果调用者不需要使用引用来修改存储在向量中的对象,则强烈建议按值传递它。 The performance hit is negligible: two
int
s instead of one pointer means 8 vs 4 bytes on most 32 bit architectures, and 8 bytes vs 8 bytes on most 64 bit machines (and also accessing the fields via pointer has a small cost). 性能下降的影响可以忽略不计:在大多数32位体系结构上,两个
int
而不是一个指针意味着8个字节对4个字节,而在大多数64位机器上则意味着8个字节对8个字节(而且通过指针访问字段的开销很小)。
This kind of micro-optimization should be the last of your concerns. 这种微优化应该是您最后关心的问题。 Your top priority is to write correct and working code, and the last thing you should do is to let micro-optimization get in the way of this aim.
您的头等大事是编写正确且有效的代码,最后要做的就是让微优化妨碍实现此目标。
Then, if you experience performance problems, you'll profile your application to find where the bottlenecks are and optimize those critical points. 然后,如果遇到性能问题,将对应用程序进行概要分析,以找出瓶颈所在,并优化这些关键点。
You cannot return a reference to a local variable, because the local variable no longer exists when the function returns. 您无法返回对局部变量的引用,因为函数返回时该局部变量不再存在。
You need to return by-value, not by-reference (ie CARD STACK::peek() { ... }
). 您需要返回按值而不是按引用(即
CARD STACK::peek() { ... }
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.