C++ 如何在链表前面添加和返回节点
当我用链表做一个小游戏的时候。我有一张班级电话卡C++ 如何在链表前面添加和返回节点,c++,pointers,linked-list,C++,Pointers,Linked List,当我用链表做一个小游戏的时候。我有一张班级电话卡 class card { public: int number; int suit; static int uniquenumber; card(); void showcard(); card * next; }; 然后对于下面的链表结构,我想将卡片添加到链表的前面 void collection::add(card a) { card *temp = new card(a);
class card
{
public:
int number;
int suit;
static int uniquenumber;
card();
void showcard();
card * next;
};
然后对于下面的链表结构,我想将卡片添加到链表的前面
void collection::add(card a)
{
card *temp = new card(a);
temp->next = start;
start = temp;
}
card collection::deal(){
card *temp = start->next;
start->next = nullptr;
start = temp;
return start;
}
但是我不能得到我想要的结果。此外,还有另一个功能需要从链接列表的前面移除一张卡,然后返回该卡。我不知道如何从链接列表返回节点
void collection::add(card a)
{
card *temp = new card(a);
temp->next = start;
start = temp;
}
card collection::deal(){
card *temp = start->next;
start->next = nullptr;
start = temp;
return start;
}
这种方法只会返回一个错误,即“无法将”card*“转换为”card”“如果您有指针变量,您可以通过取消引用指针来获取指针引用的实际值 尝试
return*start代码>您的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();
};
但是,如果您不能使用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();
};
#包括
collection::collection()
:开始(空PTR)
{
}
collection::collectionItem::collectionItem(常数卡&a,collectionItem*n)
:卡片(a),下一张(n)
{
}
集合::~collection()
{
collectionItem*项目=开始;
while(项目)
item=std::unique_ptr(item)->next;
}
无效集合::添加(常量卡和a)
{
开始=新收集项目(a,开始);
}
卡片收集::交易()
{
如果(!start)抛出std::runtime_错误(“甲板为空!”);
标准:唯一的ptr温度(启动);
开始=临时->下一步;
返回温度->卡片;
}
添加
步行时间:
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;
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
}
作为确保调用者释放返回的卡指针的工具
另一种可能是通过这种方式将链表与卡
分开收藏
的用户只看到卡
s,而不知道卡
s是如何存储在收藏
中的,这将无法满足给定的要求:“从链接列表的前面取出一张卡,然后将卡退回。”“。如果您只是返回
已解除引用的指针,则不会从列表中删除卡
。如果您从列表中删除卡
,您仍然必须销毁它,因此您不能取消对它的引用并同时销毁它。您必须复制卡
,销毁列表中的卡
,然后返回该副本。在第一次重写add()
时,为什么要通过非常量ref传递参数?谢谢您的修复,Remy@我不想再打开一罐虫子来解释一些无关紧要的事情的原因和方法。我觉得我已经有太多的事情要做了,所以我只留下了一条评论,上面有一个关键术语,如果提问者感兴趣的话,可以查阅。再想想,你是对的@bipll。解释可以是任何一种方式,所以我最好使用const
并建议他们自己查找原因。
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?
}
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
}