确认基本c++;语法 我是一个java程序员,转换到C++。我有一个类中的数据列表。我想返回存储在类变量中的列表的内容,然后生成一个新列表并将其存储在类变量中,这样就可以开始向空列表添加新数据。我想我知道怎么做,但我想再检查一遍,因为我对引用和C++内存管理是新的,以后不希望有愚蠢的内存泄漏。(注意,我不能轻易地复制我的实际代码,所以我只是在重写它,如果我输入错误,请原谅)

确认基本c++;语法 我是一个java程序员,转换到C++。我有一个类中的数据列表。我想返回存储在类变量中的列表的内容,然后生成一个新列表并将其存储在类变量中,这样就可以开始向空列表添加新数据。我想我知道怎么做,但我想再检查一遍,因为我对引用和C++内存管理是新的,以后不希望有愚蠢的内存泄漏。(注意,我不能轻易地复制我的实际代码,所以我只是在重写它,如果我输入错误,请原谅),c++,reference,C++,Reference,我相信正确的语法应该是这样的: //mylist is typedef of a list type mylist& temporaryList=classList; classList=myList(); return classList; mylist tmp = classList; classList.clear(); return tmp; mylist tmp = classList; classList = new mylist(); return tmp; 这个语法

我相信正确的语法应该是这样的:

//mylist is typedef of a list type
mylist& temporaryList=classList;
classList=myList();
return classList;
mylist tmp = classList;
classList.clear();
return tmp;
mylist tmp = classList;
classList = new mylist();
return tmp;
这个语法正确吗?另外,我是否需要担心在任何时候释放返回变量或类列表变量,或者RIAA是否会为我处理所有这些

很抱歉问这么简单的问题,但谢谢你确认我的假设

mylist& temporaryList=classList;
tempraryList
是一个参考。当您更改
类列表时,它也会更改。试试这个:

mylist tempraryList = classList;
这将复制mylist的复制构造函数,创建一个新的构造函数,而不仅仅是对另一个构造函数使用别名


这是返回一个你刚刚决定应该是一个新的列表。您想返回
临时列表
。但是,请确保它不是通过引用返回的,因为
temporaryList
将超出范围(清理自身,因为它是在堆栈上分配的),并且最终将得到一个悬空引用


同样,通常情况下,类可能会提供一种
reset
函数,而不是指定默认构造函数的结果,这样做不会增加另一个对象的开销。

chris提到使用成员函数重置或清除对象,如下所示:

//mylist is typedef of a list type
mylist& temporaryList=classList;
classList=myList();
return classList;
mylist tmp = classList;
classList.clear();
return tmp;
mylist tmp = classList;
classList = new mylist();
return tmp;
但是如果你一开始就避免抄袭,你通常会做得更好

mylist tmp;
std::swap(tmp,classList);
return tmp;
另外,我是否需要担心在任何时候释放返回变量或类列表变量,或者RIAA是否会为我处理所有这些

你不需要
删除
资源,除非你在某处
新建
它们。如果您确实使用了
new
,那么您还应该使用智能指针,这样您就不必
删除任何内容

<>从C++中了解C++最重要的事情之一是C++对象默认值为java对象。即:

class A {
    bool bar_called;
public:
    A() : bar_called(false) {}
    void bar() { bar_called = true; }
    bool has_bar_been_called_on_this_object() { return bar_called; }
};

void foo(A a) {
    a.bar();
}

int main() {
    A a;
    foo(a);
    std::cout << a.has_bar_been_called_on_this_object() << '\n';
}
从你提出的C++代码判断,你可以在java中做这样的事情:

//mylist is typedef of a list type
mylist& temporaryList=classList;
classList=myList();
return classList;
mylist tmp = classList;
classList.clear();
return tmp;
mylist tmp = classList;
classList = new mylist();
return tmp;
< C++中的等价物是:

mylist *tmp = classList; // classList is a pointer to a new'd up list.
classList = new mylist();
return tmp;
<>但是这不是IdOrthC++。在C++中,一般不想使用指针,如果要使用智能指针< /p>
std::shared_ptr<mylist> tmp = classList; // classList is a std::shared_ptr<mylist>
classList = std::make_shared<mylist>();
return tmp;

正如@chris指出的那样,您在使用引用时遇到了一个问题,引用具有一个很好的特性,即它们以很少甚至没有成本的方式别名实际对象,但在您的情况下,这意味着当您重置成员列表时,您正在重置程序中的唯一列表

正如@chris还指出的那样,对代码的简单天真的修复是复制列表,然后重置原始列表:

mylist getAndClear() {
   mylist temporaryList=classList;    // make a copy
   classList=myList();                // reset the internal
   return temporaryList;              // return the **copy**
}
现在,这种方法的问题是,当您知道原始列表将立即被销毁时,您将承担复制成本。您可以通过使用复制和交换习惯用法(*)来避免这一成本:

mylist getAndClear(){ mylist tmp;//空 swap(tmp,classList);//交换内容,现在classList为空 //tmp保存数据 返回tmp; }

这是假设
mylist
std::list
。如果不是,请确保实现
swap
(或者在C++11移动构造函数中,这将启用有效的
std::swap



(*)虽然这似乎不是复制和交换习惯用法的直接应用,但实际上是,要应用的修改正在清除列表。执行复制并将更改应用于副本(在这种情况下,由于更改正在清空副本,因此避免了复制),然后在操作成功完成后交换内容。

我有一个惊人的怀疑,您可能没有深入研究指针与引用。如果你有,请原谅我,但我很好地解释了它们。谢谢。我曾试图使用别名来避免交换,但今天回顾这一点(而不是周五我半睡半醒的时候),很明显我的语法是错误的。我假设swap的交换方式更为复杂(也就是说,它没有使用函数指针来避免不必要地复制列表节点中的数据)。现在我觉得这太愚蠢了,我应该意识到像这样的C函数在交换时可以避免不必要的复制。效率是C最终存在的全部原因。