Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在链表前面添加和返回节点_C++_Pointers_Linked List - Fatal编程技术网

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 
}