C++ 这两者有什么区别?

C++ 这两者有什么区别?,c++,pointers,map,C++,Pointers,Map,有谁能解释一下在地图容器中插入新对象所使用的以下方法的区别吗?我已经知道指针之类的东西了,我对虚拟内存不是很深入,只是基本的(地址等) #包括“StdAfx.h” #包括 #包括 #包括 #包括 使用名称空间std; 库塞尔级 { 公众: CUser(){Init();}; ~CUser(){}; 公众: BOOL m_bActive; 布尔姆布格丁; 系统时间m_系统时间; void Init(); }; void CUser::Init() { (*此).m_bActive=FALSE; m

有谁能解释一下在地图容器中插入新对象所使用的以下方法的区别吗?我已经知道指针之类的东西了,我对虚拟内存不是很深入,只是基本的(地址等)

#包括“StdAfx.h”
#包括
#包括
#包括
#包括
使用名称空间std;
库塞尔级
{
公众:
CUser(){Init();};
~CUser(){};
公众:
BOOL m_bActive;
布尔姆布格丁;
系统时间m_系统时间;
void Init();
};
void CUser::Init()
{
(*此).m_bActive=FALSE;
m_bLoggedIn=假;
GetSystemTime(&m_sysTime);
}
int main(int argc,char*argv[])
{
地图博物馆地图;
//这两者有什么区别
{   
库塞尔-普瑟;
pUser.m_bActive=FALSE;
pUser.m_bLoggedIn=FALSE;
GetSystemTime(和pUser.m_系统时间);
博物馆地图插页(制作一对(351,&pUser));
}
//这个呢?
{
CUser*pUser=新CUser;
if(pUser)
{
pUser->m_bActive=TRUE;
pUser->m_bLoggedIn=TRUE;
GetSystemTime(&pUser->m_系统时间);
博物馆地图插页(制作成对(351,pUser));
}
}
/*迭代器it=mUserMap.find(351);
if(it==mUserMap.end())
标准::cout
pUser(对象)不可用(已删除),mUserMap中的指针无效

{
    CUser *pUser = new CUser;
    if( pUser )
    {
        pUser->m_bActive = TRUE;
        pUser->m_bLoggedIn = TRUE;
        GetSystemTime( &pUser->m_sysTime );
        mUserMap.insert( make_pair( 351, pUser ) );
    }
}
//pUser is not available here

pUser(Pointer!!)不可用(已删除),内存仍在声明中,因此mUserMapis中的指针有效!

在第一种情况下,
pUser
在堆栈上创建,当其名称超出范围时(即在下一个结束的花括号处)将自动删除。一般来说,插入指针将对象堆叠到容器中是不明智的,因为当容器仍有指向对象的值时,对象将不再存在。在最好的情况下,这可能会导致崩溃。在最坏的情况下,这可能会导致不稳定且难以在代码的较远部分找到错误。

区别在于通过调用
new
创建的对象是在堆上而不是在堆栈上创建的。这意味着一旦指针超出范围,分配的内存仍然存在于堆上,您可以通过存储在映射中的指针安全地引用它

在第一种情况下,您在堆栈上创建一个对象,并将其地址添加到映射中。这意味着,当本地创建的变量超出范围时,它将被销毁,并且映射中的指针现在指向一个不再存在的变量。这无疑会导致代码中出现问题

如果必须使用指针而不是实际对象本身,请使用第一种方法。 当您使用
new
时,内存将一直保留,直到您删除它(或者让另一个对象像共享指针一样处理它)。堆栈对象一旦超出范围就会被销毁

//what is the difference between this
{   
    CUser pUser;
    pUser.m_bActive = FALSE;
    pUser.m_bLoggedIn = FALSE;
    GetSystemTime( &pUser.m_sysTime );
    mUserMap.insert( make_pair( 351, &pUser ) );
}
这将创建一个本地对象:您的
pUser
变量仅存在于该块的范围内,并且在到达最后一个
}
时不再存在。这意味着它的析构函数被调用,它所在的内存被回收并可以重用

现在,当您在地图中存储指向此短期对象的指针时,您正在存储一个问题。如果在该块的关闭
}
后的任何时间取消引用该指针,则调用的是未定义的行为。这可能有用。它有时可能奏效,然后开始失败。基本上,这是一个逻辑错误,是不可预测的错误的一个很好的来源

//and this?
{
    CUser *pUser = new CUser;
    if( pUser )
    {
        pUser->m_bActive = TRUE;
        pUser->m_bLoggedIn = TRUE;
        GetSystemTime( &pUser->m_sysTime );
        mUserMap.insert( make_pair( 351, pUser ) );
    }
}

在这里,您显式地创建了一个实例,该实例将超过封闭范围,一切正常。您无需检查
new
是否返回
NULL
:除非您明确要求,否则它将抛出异常。

Wow伙计们,非常感谢!!我不知道有这么多人愿意帮忙!我会继续发布我的问题,期待你们成为专家。再次感谢!
//what is the difference between this
{   
    CUser pUser;
    pUser.m_bActive = FALSE;
    pUser.m_bLoggedIn = FALSE;
    GetSystemTime( &pUser.m_sysTime );
    mUserMap.insert( make_pair( 351, &pUser ) );
}
//and this?
{
    CUser *pUser = new CUser;
    if( pUser )
    {
        pUser->m_bActive = TRUE;
        pUser->m_bLoggedIn = TRUE;
        GetSystemTime( &pUser->m_sysTime );
        mUserMap.insert( make_pair( 351, pUser ) );
    }
}