STL图:访问违规读取位置
STL map: Access violatoin reading location
这是我的代码:
class Base
{
public:
virtual void show() const = 0;
};
class Child : public Base
{
private:
static const int i = 1;
public:
virtual void show() const
{
cout << i;
}
};
map<int, const Base &> myMap{
{ 0, Child() },
{ 1, Child() },
};
Base & b = Child();
int main()
{
b.show();
myMap.at(0).show(); // This provokes the error
system("pause>NUL");
return 0;
}
如您所见,我正在尝试使用 global
(或 static
)数据,它将调用一些 virtual
函数。当我测试 Base & b = Child();
和 main
: b.show();
时,一切顺利。
但是,如果我像上面那样使用 map
,我会得到一个错误:
0xC0000005: Access violatoin reading location 0x00000000
.
我尝试调试这段代码,我发现当它到达时 myMap.at(0).show();
,我得到了这个:
好像虚函数的table是Unable to read
...
然后我尝试使用指针:
map<int, Base *>
和 {0, new Child()}
.
这行得通。
看来这个错误是临时引用的。
但我不知道为什么 b
有效。 b
也是临时参考。
在我看来,这个map
包含了很多b
.
为什么 b
有效而 map
无效?
您有一张参考临时文件的地图。我很惊讶甚至编译
map<int, Base &> myMap{
{ 0, Child() },
{ 1, Child() },
};
删除引用并切换到 unique_ptr
std::map<int, std::unique_ptr<Base>> myMap;
您可以在此地图中插入元素 using this method. This will prevent object slicing。
你在这里再次做同样的事情
Base & b = Child();
You cannot hold non-const references to temporary objects
MSVC 确实允许影响对引用的临时引用,这意味着 Base & b = Child();
被接受并正确处理,即使它是 不是 标准 C++ 并且被其他人拒绝编译器(并且可能会被更高版本的 MSVC 拒绝)
但即使是 MSVC 也不接受引用的 stl 容器。
因此您应该使用 map<int, Base>
(无引用,存储对象的副本)或 map<int, Base *>
(存储指向对象的指针)。在后一种情况下,you 必须明确处理对象的销毁。您还可以使用智能指针、unique_ptr
或shared_ptr
让stl关心自动销毁。
这是我的代码:
class Base
{
public:
virtual void show() const = 0;
};
class Child : public Base
{
private:
static const int i = 1;
public:
virtual void show() const
{
cout << i;
}
};
map<int, const Base &> myMap{
{ 0, Child() },
{ 1, Child() },
};
Base & b = Child();
int main()
{
b.show();
myMap.at(0).show(); // This provokes the error
system("pause>NUL");
return 0;
}
如您所见,我正在尝试使用 global
(或 static
)数据,它将调用一些 virtual
函数。当我测试 Base & b = Child();
和 main
: b.show();
时,一切顺利。
但是,如果我像上面那样使用 map
,我会得到一个错误:
0xC0000005: Access violatoin reading location 0x00000000
.
我尝试调试这段代码,我发现当它到达时 myMap.at(0).show();
,我得到了这个:
好像虚函数的table是Unable to read
...
然后我尝试使用指针:
map<int, Base *>
和 {0, new Child()}
.
这行得通。
看来这个错误是临时引用的。
但我不知道为什么 b
有效。 b
也是临时参考。
在我看来,这个map
包含了很多b
.
为什么 b
有效而 map
无效?
您有一张参考临时文件的地图。我很惊讶甚至编译
map<int, Base &> myMap{
{ 0, Child() },
{ 1, Child() },
};
删除引用并切换到 unique_ptr
std::map<int, std::unique_ptr<Base>> myMap;
您可以在此地图中插入元素 using this method. This will prevent object slicing。
你在这里再次做同样的事情
Base & b = Child();
You cannot hold non-const references to temporary objects
MSVC 确实允许影响对引用的临时引用,这意味着 Base & b = Child();
被接受并正确处理,即使它是 不是 标准 C++ 并且被其他人拒绝编译器(并且可能会被更高版本的 MSVC 拒绝)
但即使是 MSVC 也不接受引用的 stl 容器。
因此您应该使用 map<int, Base>
(无引用,存储对象的副本)或 map<int, Base *>
(存储指向对象的指针)。在后一种情况下,you 必须明确处理对象的销毁。您还可以使用智能指针、unique_ptr
或shared_ptr
让stl关心自动销毁。