在指针定义的行为映射中是否为nullptr的默认值?

MrB*_*ido 6 c++ big-o time-complexity c++11

以下代码似乎始终遵循true分支.

#include <map>
#include <iostream>

class TestClass {
  // implementation 
}

int main() {
  std::map<int, TestClass*> TestMap;
  if (TestMap[203] == nullptr) {
    std::cout << "true";
  } else {
    std::cout << "false";
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

它是否为未初始化的指针定义了行为nullptr,或者是我的编译器的工件?

如果没有,我如何确保以下代码的可移植性?目前,我正在使用类似的逻辑来返回正确的单例实例log file:

#include <string>
#include <map>    

class Log {
  public:
    static Log* get_instance(std::string path);
  protected:
    Log(std::string path) : path(path), log(path) {};
    std::string path;
    std::ostream log;
  private:
    static std::map<std::string, Log*> instances;
};

std::map<std::string, Log*> Log::instances = std::map<std::string, Log*>();

Log* Log::get_instance(std::string path) {
  if (instances[path] == nullptr) {
    instances[path] = new Log(path);
  }
  return instances[path];
}
Run Code Online (Sandbox Code Playgroud)

一种解决方案是使用与此类似的东西,其中使用特殊函数在检查时提供默认值map.但是,我的理解是这会导致查找的复杂性O(n)而不是O(1).这在我的场景中不是太大的问题(只会有少量的日志),但更好的解决方案是以某种方式强制指针类型Log*的引用nullptr默认情况下,从而使查找检查O(1)和便携式相同时间.这是可能的,如果可以的话,我该怎么做?

cel*_*chk 9

映射总是对其成员进行值初始化(当然,在它们未进行复制初始化的情况下),内置类型的值初始化意味着零初始化,因此它确实是定义的行为.对于访问operator[]在调用之前不存在的元素时生成的新密钥的值部分尤其如此.

但是请注意,一个uninizialized指针并不一定是空指针; 实际上,只是读取它的值已经调用了未定义的行为(在某些情况下可能会在某些平台上出现分段错误).关键是地图中的指针不是未初始化的.所以如果你写的话

void foo()
{
  TestClass* p;
  // ...
}
Run Code Online (Sandbox Code Playgroud)

p不会被初始化nullptr.

但请注意,您可能希望检查是否存在,以避免累积不必要的条目.您将使用find成员函数检查是否存在:

map<int, TestClass*>::iterator it = TestMap.find(203);
if (it == map.end())
{
  // there's no such element in the map
}
else
{
  TestClass* p = it->second;
  // ...
}
Run Code Online (Sandbox Code Playgroud)

  • @MrBushido号`TestClass*p();`不声明变量,它声明一个不带参数的函数并返回`TestClass*`. (2认同)
  • 答案是使用错误的术语.如果`operator []`中的新元素不存在,`std :: map`将*value-initialize*(不是*default-initailize*).重要的是要注意区别,因为*POD类型的默认 - 初始化*使它们*未初始化*,而*值初始化*意味着对于那些相同类型的*零初始化*.替换*值初始化*其中*default-initialization*出现在答案中将使其正确. (2认同)