C++ 关于映射和迭代器的理论澄清
如果我有一个映射为私有成员的类,例如C++ 关于映射和迭代器的理论澄清,c++,dictionary,iterator,C++,Dictionary,Iterator,如果我有一个映射为私有成员的类,例如 class MyClass { public: MyClass(); std::map<std::string, std::string> getPlatforms() const; private: std::map<std::string, std::string> platforms_; }; MyClass::MyClass() : { platforms_["key1"]
class MyClass
{
public:
MyClass();
std::map<std::string, std::string> getPlatforms() const;
private:
std::map<std::string, std::string> platforms_;
};
MyClass::MyClass()
:
{
platforms_["key1"] = "value1";
// ...
platforms_["keyN"] = "valueN";
}
std::map<std::string, std::string> getPlatforms() const
{
return platforms_;
}
class-MyClass
{
公众:
MyClass();
std::map getPlatforms()常量;
私人:
地图平台;
};
MyClass::MyClass()
:
{
平台[“键1”]=“值1”;
// ...
平台[“键”]=“值”;
}
std::map getPlatforms()常量
{
返回平台;
}
在我的主要功能中,这两段代码之间会有区别吗
代码1:
MyClass myclass();
std::map<std::string, std::string>::iterator definition;
for (definition = myclass.getPlatforms().begin();
definition != myclass.getPlatforms().end();
++definition){
std::cout << (*definition).first << std::endl;
}
MyClass MyClass();
std::map::迭代器定义;
for(definition=myclass.getPlatforms().begin();
定义!=myclass.getPlatforms().end();
++(定义){
std::coutgetPlatforms()
通过值而不是引用返回映射,这通常是个坏主意
您已经展示了一个为什么这是一个坏主意的示例:
getPlatforms()
是来自同一原始映射的不同副本上的迭代器。您遇到的一个问题是,您应该使用常量迭代器
而不是迭代器
。这是因为getPlatforms
函数是const
限定的,而映射迭代器中的函数begin()
不是;您必须使用const
限定的const\u迭代器begin()const
来明确告诉编译器您不会修改类的任何成员
注意:这只是代码1的情况,顺便说一下,它应该返回const&
你能告诉我这两段不同代码之间的理论基础吗
按值返回时,返回数据的深度副本
当调用myclass.getPlatforms().begin();
和myclass.getPlatforms().end();
时,实际上是在构造数据的两个副本,然后从一个副本获取开始迭代器,从另一个副本获取结束迭代器。然后,比较两个迭代器是否相等;这是未定义的行为
导致运行时错误,无法访问某个位置的内存
这是因为definition
被初始化,然后用于创建它的临时对象被删除,从而使迭代器指向的数据无效。然后,您尝试通过迭代器使用数据。错误。getPlatforms()的返回值
不是const
-限定的,因此完全可以使用变异迭代器。@AngeW-很抱歉,我忘了澄清它只在const时出现&
返回类型const
不是问题。它们有一个迭代器指向不再存在的对象。@NathanOliver-但是如果您通过const&
返回>,代码1的编译和运行方式与代码2相同would@Joe仍然可以工作。请看:正如Joe指出的,getPlatforms()是常量,因此通过非常量引用返回映射将是一个问题。(通过常量方法返回值没有问题,但正如我试图解释的,通过值返回是一个坏主意)。因此,您希望通过常量返回&
,在这种情况下,Joe关于常量迭代器的说法将变得正确。谢谢。如果您不介意的话,可以问以下几个问题:(1)如何通过引用返回映射?(2)何时通过引用而不是通过值返回对象更好?而不是std::map getPlatforms()const;
使用std::map const&getPlatforms()const;
然后需要切换到代码1的const_迭代器。要使代码2与更正后的代码1具有可比性,您需要进行上述注释中描述的两个更改,并同时更改std::map platforms=myclass.getPlatforms();
into std::map const&platforms=myclass.getPlatforms()59449
MyClass myclass();
std::map<std::string, std::string> platforms = myclass.getPlatforms();
std::map<std::string, std::string>::iterator definition;
for (definition = platforms.begin();
definition != platforms.end();
++definition){
std::cout << (*definition).first << std::endl;
}