确认基本 C++ 语法
confirmation of basic c++ syntax
我是一个切换到C++的Java程序员。 我有一个类中的数据列表。 我想返回存储在类变量中的列表的内容,然后生成一个新列表并将其存储在类变量中,以便我可以开始向空列表中添加新数据。 我想我知道该怎么做,但我想仔细检查,因为我是参考和 c++ 内存管理的新手,以后不想出现愚蠢的内存泄漏。 (注意,我不能轻易复制我的实际代码,所以我只是重写它,如果我打错了什么,请原谅我)。
我相信正确的语法是这样的:
//mylist is typedef of a list type
mylist& temporaryList=classList;
classList=myList();
return classList;
此语法正确吗? 另外,我是否必须担心随时释放返回的变量或类列表变量,或者RIAA会为我处理这一切吗?
很抱歉问这么简单的问题,但感谢您确认我的假设。
mylist& temporaryList=classList;
tempraryList
是一个参考。当你改变classList
时,它也会改变。试试这个:
mylist tempraryList = classList;
这将复制 mylist 的复制构造函数,创建一个新的构造函数,而不仅仅是别名另一个。
return classList;
这是返回您刚刚决定应该是新列表的那个。您想返回temporaryList
.但是,请确保它不是通过引用返回的,因为temporaryList
将超出范围(清理自身,因为它是在堆栈上分配的),并且您最终会得到一个悬而未决的引用。
同样,通常,类可能会提供一种reset
函数来执行此操作,而不是分配默认构造函数的结果,而无需另一个对象的开销。
正如@chris指出的那样,您在使用引用时遇到了一个问题,引用具有很好的功能,即它们以很少甚至免费的方式为实际对象设置别名,但在您的情况下,这意味着当您重置成员列表时,您正在重置程序中的唯一列表。
正如@chris还指出的那样,对代码的简单修复是复制列表,然后重置原始列表:
mylist getAndClear() {
mylist temporaryList=classList; // make a copy
classList=myList(); // reset the internal
return temporaryList; // return the **copy**
}
现在,这种方法的问题在于,当您知道原始列表将立即被销毁时,您将产生复制成本。您可以通过使用复制和交换习惯用语(*)来避免该成本:
mylist getAndClear() { 我的利斯特TMP; 空 swap( tmp, classList ); 交换内容,现在类列表为空 TMP 保存数据 返回 TMP; }
这是假设mylist
是一个std::list
。如果不是,请确保实现swap
(或在 C++11 个移动构造函数中,这将实现高效的std::swap
)。
(*) 虽然这似乎不是复制和交换习惯用法的直接应用,但实际上确实如此,要应用的修改是清除列表。执行复制并对副本应用更改(在这种情况下,将避免复制,因为更改会清空它),然后在操作成功完成后交换内容。
Chris 提到使用成员函数来重置或清除对象,如下所示:
mylist tmp = classList;
classList.clear();
return tmp;
但是,您通常可以通过首先避免复制来做得更好。
mylist tmp;
std::swap(tmp,classList);
return tmp;
另外,我是否必须担心随时释放返回的变量或类列表变量,或者RIAA会为我处理这一切吗?
除非在某处new
资源,否则无需delete
资源。如果你确实使用new
那么你也应该使用智能指针,这样你仍然不必delete
任何东西。
关于来自 Java C++,要了解的最重要的事情之一是C++对象默认情况下是类似于值的对象。那是:
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';
}
输出将指示柱线尚未在a
上调用。Java使用指针,但试图隐藏指针。因此,一旦你弄清楚了C++事情对你来说应该更有意义,然后你就能弄清楚如何不使用指针。
Object o = new Object(); // Java hides the fact that o is a pointer to an Object, but fails to hide the consequences
Object b = o; // b is a pointer to an object, the same Object o points to.
// Equivalent C++
Object *o = new Object();
Object *b = o;
从你提出的C++代码来看,在 Java 中,你会按照你的要求做这样的事情:
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;
然而,这并不是偶像C++。在C++中,您通常不想使用指针,如果您这样做,则希望使用智能指针
std::shared_ptr<mylist> tmp = classList; // classList is a std::shared_ptr<mylist>
classList = std::make_shared<mylist>();
return tmp;
或
std::unique_ptr<mylist> tmp = std::move(classList); // classList is a unique_ptr
classList = std::unique_ptr<mylist>(new mylist()); // careful here, don't go calling a bunch of functions inside the mylist initializer, it's dangerous for reason beyond the scope of this post
return tmp;
但C++方法实际上是完全避免指针。
mylist tmp; // classList is not a pointer at all
std::swap(tmp,classList); // the values of classList and tmp are swapped
return tmp; // tmp is returned by value, tmp has the same value as classList, but is not the same object, tmp and classList are objects, not pointers to objects as they are in Java or in the above C++ examples.
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- C++语法运算符功能?
- C++使用 rand 定义函数语法
- 什么文件可以修改 atom 的C++语法?
- 创建模板嵌套类实例的语法?
- C++语法差异:二维和一维数组(指针算术)
- 将信息输入到下面显示的结构向量中的正确语法/格式是什么