Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于映射和迭代器的理论澄清_C++_Dictionary_Iterator - Fatal编程技术网

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::cout
getPlatforms()
通过值而不是引用返回映射,这通常是个坏主意

您已经展示了一个为什么这是一个坏主意的示例:


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;
}