我正在使用linked_list制作一款小游戏。我有班级电话卡
class card
{
public:
int number;
int suit;
static int uniquenumber;
card();
void showcard();
card * next;
};
然后对于以下的linked_list结构,我想将卡添加到linked_list的前面。
void collection::add(card a)
{
card *temp = new card(a);
temp->next = start;
start = temp;
}
但我无法得到我想要的结果。此外,还有另一个功能需要从linked_list的前面删除卡,并返回卡。我不知道如何从linked_list返回一个节点。
card collection::deal(){
card *temp = start->next;
start->next = nullptr;
start = temp;
return start;
}
这种方式只会给我一个错误,说“无法转换”卡*“到”卡“”
答案 0 :(得分:2)
参观的时间:
void collection::add(card a) // pass by value. a is a copy
{
card *temp = new card(a); // makes a dynamically allocated copy of the copy.
temp->next = start; // looks right
start = temp; // looks right
}
此功能没有明显错误,但如果你想要
myCollection.add(mycard);
然后期望使用mycard
,就好像它在myCollection
中一样,你运气不好。 mycard
的副本位于mycollection
。我们可以略微改进以减少复制量,
void collection::add(const card & a) // pass by reference. a is the source. One less copy
// Look up const correctness for more information
// on the use of const here
{
card *temp = new card(a); // makes a dynamically allocated copy of the copy.
temp->next = start;
start = temp;
}
但是如果你希望mycard
在列表中而不是它的副本中,你需要以非常不同的方式做事
void collection::add(card * a) // pass by reference via a pointer
{
a->next = start;
start = a;
}
并使用类似:
card * mycard = new card()
// set members of *mycard. Or better, make a smarter constructor to set them for you
myCollection.add(mycard);
card collection::deal(){
card *temp = start->next; //temp points to the second item on the list
start->next = nullptr; // cur off start from the rest of the list
start = temp; // whups! Just lost the first item in the list
return start; // start is a pointer. The return type is not. Need to dereference
}
修复一个:deference指针返回它。
card collection::deal(){
card *temp = start->next;
start->next = nullptr;
start = temp;
return *start; // returns a copy of the second card in the list
}
下一步修复:返回正确的卡
card collection::deal(){
card *temp = start; //temp points to the first item on the list
start = start->next; // advance start to second item on the list
temp->next = nullptr; // cut former first item off from from the list
return *temp; // returns a copy of the former first item. But what of temp?
}
下一步修正:temp
被泄露了。没有人指出它,记忆永远不会被释放。
card collection::deal(){
card *temp = start;
start = start->next;
temp->next = nullptr;
card rval(*temp); // copy former first node
delete temp; // free former first node
return rval; // return copy.
}
您还可以返回指向已删除项目的指针,并将其释放给调用者。这有点狡猾。
card * collection::deal(){
card *temp = start; //temp points to the first item on the list
start = start->next; // advance start to second item on the list
temp->next = nullptr; // cut former first item off from from the list
return temp; // returns former first item
}
on click作为确保调用者释放返回的card
指针的工具。
另一种可能性是将链接列表与card
分开。这样collection
的用户只会看到card
,并且不知道card
是如何存储的在collection
内。
答案 1 :(得分:1)
您的add()
看起来不错,但您的deal()
完全错了。它应该看起来更像是这样:
card collection::deal()
{
if (!start) throw std::runtime_error("deck is empty!");
card *temp = start;
start = temp->next;
card theCard = *temp;
c.next = nullptr;
delete temp;
return theCard;
}
您可以使用更具创意的编码来简化代码,例如:
class card
{
public:
int number;
int suit;
card * next;
static int uniquenumber;
card();
card(const card &src, card *n = nullptr);
card& operator=(const card &rhs);
void showcard();
};
#include <memory>
card::card()
: number(0), suit(0), next(nullptr)
{
}
card::card(const card &src, card *n)
: number(src.number), suit(src.suit), next(n)
{
}
card& card::operator=(const card &rhs)
{
if (&rhs != this)
{
number = rhs.number;
suit = rhs.suit;
// don't copy 'next'!
next = nullptr;
}
return *this;
}
void collection::add(const card &a)
{
start = new card(a, start);
}
card collection::deal()
{
if (!start) throw std::runtime_error("deck is empty!");
std::unique_ptr<card> temp(start);
start = start->next;
return *temp;
}
但是,话虽如此,从设计的角度来看,card
根本不应该有next
成员。您应该将card
与链接列表的实现分开(这将允许您稍后更改列表的实现,而无需更改card
以匹配)。您需要一个包含卡对象的列表,而不是 卡对象的列表。
您应该使用std::list
进行分离,例如:
#include <list>
class card
{
public:
int number;
int suit;
static int uniquenumber;
card();
void showcard();
};
class collection
{
private:
std::list<card> cards;
public:
void add(const card &a);
card deal();
};
void collection::add(const card &a)
{
cards.push_front(a);
}
card collection::deal()
{
if (cards.empty()) throw std::runtime_error("deck is empty!");
card theCard = cards.front();
cards.pop_front();
return theCard;
}
但是,如果你不能使用std::list
,那么你可以使用更像这样的东西:
class card
{
public:
int number;
int suit;
static int uniquenumber;
card();
void showcard();
};
class collection
{
private:
struct collectionItem
{
card theCard;
collectionItem *next;
collectionItem(const card &a, collectionItem *n);
};
collectionItem *start;
public:
collection();
~collection();
void add(const card &a);
card deal();
};
#include <memory>
collection::collection()
: start(nullptr)
{
}
collection::collectionItem::collectionItem(const card &a, collectionItem *n)
: theCard(a), next(n)
{
}
collection::~collection()
{
collectionItem *item = start;
while (item)
item = std::unique_ptr<collectionItem>(item)->next;
}
void collection::add(const card &a)
{
start = new collectionItem(a, start);
}
card collection::deal()
{
if (!start) throw std::runtime_error("deck is empty!");
std::unique_ptr<collectionItem> temp(start);
start = temp->next;
return temp->theCard;
}
答案 2 :(得分:0)
如果你有指针变量,你可以得到指针取消引用指针引用的实际值。
尝试return *start;