C++ C++;-返回对象的函数
在C++ C++;-返回对象的函数,c++,C++,在molly->eatFood()上是否会出现“释放后使用”错误?除了程序结束时出现内存泄漏外,对于内存的无效使用,没有任何错误。如果在堆上创建了某些内容(例如使用new),则需要对其调用delete,以释放它 您还有许多语法错误,请更正如下 // Assume class definition for Cat is here. Cat makeCat() { Cat lady = new Cat("fluffy"); return lady; } int main (...
molly->eatFood()
上是否会出现“释放后使用”错误?除了程序结束时出现内存泄漏外,对于内存的无效使用,没有任何错误。如果在堆上创建了某些内容(例如使用new
),则需要对其调用delete
,以释放它
您还有许多语法错误,请更正如下
// Assume class definition for Cat is here.
Cat makeCat() {
Cat lady = new Cat("fluffy");
return lady;
}
int main (...) {
Cat molly = makeCat();
molly->eatFood();
return 0;
}
我认为它应该是
Cat*lady
和Cat*molly
,但是它应该是可以的。因为lady
是在堆上创建的(使用new
),所以退出makeCat
方法时它不会被销毁。所以对molly的调用是完全有效的
但是,您有内存泄漏。在使用后(将来的某个时候),您需要删除
molly
。因为您的程序结束了,所以这没什么大不了的。在一个更大的程序中,这将是一个非常大的问题。newcat(“fluffy”)
创建一个指针。您需要将Cat*
指定为返回类型。由于对象是在堆中创建的,因此在函数返回后仍然可用。问题不是“释放后使用”;更可能的情况是,您没有删除新实例。更正了您的程序,并创建了类Cat的示例实现:
Cat* makeCat()
{
Cat *lady = new Cat("fluffy");
return lady;
}
int main (int argc, char** argv)
{
Cat* molly = makeCat();
molly->eatFood();
delete molly;//This was added
return 0;
}
<>我建议你在继续之前学习一本关于C++ Cover to Cover商店的基本书籍。 如果你的编译器支持C++ 11,你可以在这里使用UngyQupTR:
Cat Cat2 created.
Food eaten by cat named Cat2.
Cat Cat1 created.
Food eaten by cat named Cat1.
Cat Cat1 destroyed.
Cat Cat2 destroyed.
程序终止时会泄漏内存吗?@Eiko:通常操作系统会释放内存,但这不能保证。对于任何不能保证的事情,都不推荐这样做。尤其是在没有释放内存的情况下。例如,谁说析构函数中不存在一段重要的代码,我同意在自己之后清理是明智的,而使用干净的代码也不需要做很多工作。(虽然我有时会读到不要浪费CPU周期的建议)@Eiko:“我有时会读到不要浪费CPU周期的建议”-忽略这个建议-这是一个没有经验的人写的不好的建议。小心。在一些非常罕见的情况下,不做清理工作,而是自杀是值得的。如果您在被操作系统调出时删除了所有分配的内存,那么关闭程序将消耗大量资源和用户时间。软件必须能够(编译选项)干净地退出,但有时自杀真的很好。:-)例如,我欢迎在Firefox和Outlook中使用它……当我返回对象sally时,这不是传递值吗?如果是,函数结束后sally不会被删除吗?如果“sally”是指makeCat中的“lady”变量,则不是。您实际上传递了一个指针(但您错过了“*”在你的代码中。凯文:阅读关于STL auto_ptr和boost shared_ptr的内容。不,在你先了解基本知识之前不要阅读关于STL的内容。@James:我希望我们可以否决投票评论。你需要了解在BASIC中内存管理是如何工作的,以便能够编写基本代码吗?首先教学生手动完成所有事情,然后再教他们手工操作是很糟糕的,他们需要把他们所学的东西全部学完,但这并不是很有帮助。凯文,这个代码仍然不能编译。@ SBI:我倾向于同意。但是,在这种情况下,我认为“杰姆斯”是在谈论C++语法的基础知识,而不是关于内存管理。至少与C#和指针的区别是无害的。它在堆栈上创建时仍然可用,因为它是通过值返回的(即复制构造回来的(尽管允许编译器省略复制))因此,除了语法错误之外,代码是良好的,并且不使用销毁的对象。尽管它可能产生不同的输出,因为C++标准不需要编译器尽可能地删除不必要的拷贝。因此,完全可以看到另外两个“CATCAT2破坏”消息(例如,没有RVO)。makeCat1
返回指针,makeCat2
返回引用?什么是:name(name)
对于构造函数中的Cat
?这称为构造函数初始值设定项列表。此列表有一个元素:如果name
数据成员带有name\ucode>参数,则初始化。它位于构造函数的参数列表之后,以冒号开头,其元素用逗号分隔。@qed makeCat2一个值(既不是引用也不是指针)。此输出表明它的复制已优化。它的行为类似于它是在main中直接创建的,从未复制过。
Cat Cat2 created.
Food eaten by cat named Cat2.
Cat Cat1 created.
Food eaten by cat named Cat1.
Cat Cat1 destroyed.
Cat Cat2 destroyed.
#include <iostream>
#include <memory>
using namespace std;
class Cat {
public:
Cat() {
cout << "Cat created" << endl;
}
~Cat() {
cout << "Cat destroyed" << endl;
}
void eatFood() {
cout << "Cat is eating food" << endl;
}
};
unique_ptr<Cat> makeCat() {
unique_ptr<Cat> lady( new Cat );
return lady;
}
int main () {
unique_ptr<Cat> molly = makeCat();
molly->eatFood();
return 0;
}
Cat created
Cat is eating food
Cat destroyed