CARD& STACK::peek()
{
if(cards.size == 0)
{
CARD temp = CARD {-1, -1};
return temp;
}
return cards.back();
}
这是我遇到麻烦的功能。
CARD
只有struct
个int
个变量,名为rank
和suit
。
STACK
是管理class
的{{1}},名为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
的地址。这样做似乎比创建我想要返回的卡片副本更有意义。
答案 0 :(得分:3)
首先,我收到一条警告,提示返回对本地变量
temp
的引用。这有什么问题?这对功能有何影响?我该怎么办?
顾名思义,局部变量是它所属函数的局部变量,因此它会在函数返回时被销毁;如果你试图返回对它的引用,你将返回对函数返回时将停止存在的东西的引用。
虽然在某些情况下这似乎无论如何都可行,但你只是幸运,因为堆栈没有被覆盖,只是调用其他功能,你会发现它会停止工作。
您有两种选择:首先,您可以按值而不是参考返回CARD
;但是,这样做的缺点是不允许调用者使用引用来修改存储在CARD
中的vector
(这可能是也可能不是)。
另一种方法是在CARD
类中存储一个静态虚拟STACK
实例,它不会有这些生命周期问题,并且当你没有元素时可以返回vector
;但是,你应该找到一种方法来“保护”它的字段,否则一个“愚蠢”的调用者可能会改变你的“单例”虚拟元素的值,搞砸了类的逻辑。可能是在CARD
中更改class
将封装其字段,如果它是虚拟元素,则会拒绝对它们的写访问。
对于cardToString
函数,你可能在对字符串做错了(我几乎肯定你在这种情况下也试图返回一个本地),但是没有看到这个功能很难分辨出来。
顺便说一下,为了避免字符串出现很多问题,我建议您使用char *
类而不是std::string
类,这样可以消除大部分丑陋和低级内存管理通常char *
。
此外,我建议您更改cardToString
以获取const
引用,因为很可能它不需要更改作为参考传递的对象,并且明确标记是一个好习惯这个事实(如果你试图改变这样的引用,编译器会警告你。)
修改强> 的
只要cardToString
和RANKS
数组正常,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() { ... }
)返回。