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