找出C++中的值语义

figuring out value semantics in C++

本文关键字:语义 C++ 找出      更新时间:2023-10-16

我有一个包含以下成员的类字符串:

Class String{
    ...
    private:
    char* word
    int length
}
String

的复制赋值返回一个 String&,并在堆上分配单词。

我还有一个用 C 编写的链表类,它有一个函数:

void *popFront(struct List *list)
{
    struct Node prevHead = list->head
    list->head = prevHead->next;
    void *info = prevHead->info;
    free(prevHead);
    return info;
}

我的任务是为使用 C 函数的C++链表编写相同的函数。这是我所拥有的:

String List::popFront()
{
    String s = (*(String *) ::popFront(&list));//casting the void * to String
    return s;
}

C++ 方法应按值返回对象。这就是我认为该方法可以做到的。然而我有内存泄漏。关于我需要如何修改 List::p opFront() 以便它按值返回的任何提示?谢谢。

首先将返回的指针本地存储为指向字符串的指针,然后创建字符串的本地副本,然后删除对象,指针指向并最终返回本地副本。

编辑:顺便说一句,您可以使用 c++11 的智能指针来避免额外的副本:

String List::popFront()
{
    auto s = std::unique_ptr<String>((String*) ::popFront(&list));  
    return *s;
}

但这可能不是,你的老师的目标。

popFront

链表中删除元素并释放节点,但不释放info部分。这是popFront调用者的责任,例如

String *s = (String *) ::popFront(&list);
delete s;

但是您还必须保留一份副本,您可以从该方法返回该副本

String List::popFront()
{
    String *s = (String *) ::popFront(&list);
    String tmp = *s;
    delete s;
    return tmp;
}

你声明String List::popFront()它返回一个对象,而不是一个指针。String s = ...声明一个对象,而不是指针或引用。因此,s赋值会构造一个新对象,s作为::popFront返回的内容的副本,然后返回s的下一个副本s本身被销毁。但是,::popFront()未链接的对象仍保留在堆上,从而产生泄漏。

不要创建String对象的中间副本,返回指向未链接对象的指针,以便调用方可以将其链接到自己的列表或在使用后delete它:

String *List::popFront()
{
    String *s = (String *) ::popFront(&list);//casting the void * to String *
    return s;
}