到期项目的要求,本周我从Java转向C ++。我面临很多麻烦,但也许更大的是“传递价值”和......显然指针:) 现在我怀疑在另一个对象的构造函数中实例化对象的命运。这里我的简单SSCCE由头文件和cpp文件组成:
#pragma once
#include <map>
class MapReferenceHolder
{
std::map<int, char*>* mapPointer;
public:
MapReferenceHolder();
~MapReferenceHolder();
void setMap(std::map<int,char*>* map);
void addSomeElementToMap();
void MapReferenceHolder::printMap();
};
这里包含main的cpp文件:
#include "MapReferenceHolder.h"
#include <iostream>
using namespace std;
std::map<int, char*>mymap;
MapReferenceHolder::MapReferenceHolder()
{
setMap(&mymap);
}
MapReferenceHolder::~MapReferenceHolder()
{
}
void MapReferenceHolder::setMap(std::map<int, char*>* map){
mapPointer = map;
}
void MapReferenceHolder::addSomeElementToMap(){
(*mapPointer)[0] = "stringONe";
(*mapPointer)[1] = "stringTwo";
}
void MapReferenceHolder::printMap(){
std::map<int, char*>::iterator it = mapPointer->begin();
while (it!=mapPointer->end()){
cout << it->first << " -> " << it->second << "\n";
it++;
}
}
int main(){
MapReferenceHolder m;
m.addSomeElementToMap();
m.printMap();
cin.get();
return 0;
}
这个简单的例子运行没有问题。但是如果我在构造函数中移动mymap实例化,即
MapReferenceHolder::MapReferenceHolder()
{
std::map<int, char*>mymap;
setMap(&mymap);
}
我得到了以下错误:
Unhandled exception at 0x00B2BD3B in Project1.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.
我想这是因为一个对象的实例只存在于定义的块内。但是我传递了对象的地址,所以它还活着!或者编译器在任何情况下都会销毁它?更重要的是......然后,正确创建一个全局变量来存储对象实例。我怎样才能正确使用构造函数?我知道这是一个“新手”问题,但我试图满足项目的开发需求,而我的业余时间很少。任何帮助将非常感谢。 问候, microvo
答案 0 :(得分:3)
对象在构造函数的末尾被销毁。所以你保存了一个不再有效的指针。
答案 1 :(得分:1)
你需要考虑C ++中的所有权(Java有一个循环检测垃圾收集器,所以给你很大的余地)。
如果MapReferenceHolder
拥有std::map
,你应该使它成为值而不是指针,如果由于某种原因需要指针,你总是可以使用它的引用。除非它们包含实际代码,否则还要删除构造函数和析构函数。
或者你可以在你的析构函数中调用delete mapPointer
,但是在这个IMO这样的简单情况下,添加额外的代码是没有好处的。
如果MapReferenceHolder
不拥有std::map
,那么您需要传入指针并以某种方式跟踪它在该类之外某处的生命周期。
答案 2 :(得分:0)
一旦超出范围,地图对象就不再存在,无论任何指针保存其地址 - 这些指针都不再有效。我建议搜索“构造函数初始化列表”可能会对你有帮助。