C++ 与C++;

C++ 与C++;,c++,new-operator,factory-pattern,virtual-functions,delete-operator,C++,New Operator,Factory Pattern,Virtual Functions,Delete Operator,我想知道删除是如何工作的? 在main function中,我删除了cfact对象。但是,cfact->Hello()仍然有效,而不是抛出错误。 调试时,我发现删除发生时,cfact释放内存。只要工厂*c2fact=newfun.newfun(“c2_事实”)行执行cfact获取一些内存位置 怎么做?请帮助我理解这个概念 class factory{ public: virtual void Hello() = 0; }; class c_fact: public factory {

我想知道删除是如何工作的? 在main function中,我删除了
cfact
对象
。但是,
cfact->Hello()
仍然有效,而不是抛出错误。 调试时,我发现删除发生时,
cfact
释放内存。只要
工厂*c2fact=newfun.newfun(“c2_事实”)行执行
cfact
获取一些内存位置

怎么做?请帮助我理解这个概念

class factory{

public:
    virtual void Hello() = 0;
};
class c_fact: public factory
{
public:
    void Hello(){
    cout << "class c_fact: public factory"<<endl;
    }
};
class c2_fact: public factory
{
public:
    void Hello(){
    cout << "class c2_fact: public factory"<<endl;
    }
};

class callFun{
public:
    virtual factory* Newfun(string data)
    {
        if(data == "c_fact")
            {return new c_fact;}
        else
            {return new c2_fact;}
    }
};
class newFun:public callFun{
public:
    factory* Newfun(string data)
    {
        if(data == "c_fact")
            {return new c_fact;}
        else if (data == "c2_fact")
            {return new c2_fact;}
    }
};
int main()
{
    newFun newfun;
    factory* cfact = newfun.Newfun("c_fact");
    delete cfact;                              //Deleted the instance
    factory* c2fact = newfun.Newfun("c2_fact");
    cfact->Hello();//Still it prints the output
    c2fact->Hello();
    system("pause");
    return 0;
}
类工厂{
公众:
虚空Hello()=0;
};
c类事实:公共工厂
{
公众:
void Hello(){

cout
delete
实际上并不会使它指向的内容无效。它只是告诉操作系统内存可以用于其他内容,并且程序不再需要它

如果它没有被其他数据覆盖,您的数据仍将在内存中,并且仍然可以访问。。这是导致许多错误的原因,这些错误在开发阶段未被检测到,稍后会出现

事实上,现在正在工作并不意味着它将一直工作。例如,如果您将代码移动到另一台计算机,或者如果您重新启动计算机,代码可能会出错


delete
之后将指针设置为
NULL
始终是一个好的做法。或者更好地使用
智能指针

这是一种未定义的行为,很可能是因为方法
Hello
没有使用任何类变量,因此没有使用
This
指针在
Hello
中,ng
this
,在调用
delete
后,您应该会看到一个无效指针:

std::cout << std::hex << this << << std::endl ;

std::cout取消引用已删除指针是未定义的行为。这意味着任何事情都可能发生,包括程序看起来“正常工作”。您不能依赖任何此类行为。

当您删除内存时,它会被释放。但是,内容通常不会更改,因此在删除后,写入该内存中的任何内容仍然存在,但您不知道它会保留多长时间,因为其他函数可以获取它并用自己的数据覆盖它

在某些编译器上,在调试模式下编译时,会标记内存,以便您可以通过重用已删除的指针来检测此类错误。但是,这不一定是默认值。因此,您永远不应重用已删除的指针。

抱歉,我无法评论。。。 我编译了您的代码,您可以看到c2fact替换了刚才销毁的cfact(输出为

类别c2_事实:公共工厂

类别c2_事实:公共工厂 )

顺便说一句,如果在创建c2fact之前放置“cfact->Hello();”,程序可能会崩溃(这似乎是您所希望的),因为mem块不会影响任何对象。请注意,此行为可能会因内存监视和其他运行进程的不同而发生变化


希望其他答案(名字的答案)能提供您所需的信息。

您希望发生什么?您正在对已删除的对象调用函数。这是未定义的行为,任何事情都可能发生,包括打印输出。@PeterWood:I want
cfact->Hello();
失败。我意外地看到了这种行为。因此,我无法理解我想问的问题。你应该使用虚拟析构函数
delete
可以使它指向的内容无效,只是不必按照标准执行。这是一个实现细节。delete也不会将内存返回给操作系统,它只会将内存返回给操作系统应用程序内存池,可能不同。这也是一个实现细节。但是,如果在正常的用户空间环境中,删除直接通过操作系统内存处理,这将是一个糟糕的实现。它们的关键字是“…可能崩溃…”。由于该程序相当短,功能不多,很可能会在未被注意的情况下运行。当然,它是编译器,甚至依赖于库。它可能会立即崩溃,也可能会在生产代码中运行多年,让您的代码在完全不同的位置崩溃。Arf我无法更新您的评论…事实上,也许我应该更正自己:如果在创建c2fact之前放置“cfact->Hello();,程序将崩溃。我刚刚用Win7;)和mingw测试了它,Anoune想用其他操作系统/编译器测试它?刚刚用gcc 3.4测试了它。在eclipse下的Windows XP上使用cygwin,它不会崩溃。编译器选项也很重要。如果你使用-g,它的行为可能与使用.I.e-O2或其他任何东西时不同。我还尝试了你建议的更改,它不会崩溃。:)比ks为了这个澄清…现在我想尝试这些我以前从未听说过的编译器选项!-g是在二进制文件中包含调试信息,因此调试器会给你源代码行和变量名。-O2是一个优化级别,因此编译器会尽可能地优化代码。但是不推荐同时使用-g和-O。