C++指针的默认构造函数是什么?

Mil*_*kov 27 c++ constructor pointers map

我有这样的代码:

class MapIndex
{
private:
    typedef std::map<std::string, MapIndex*> Container;
    Container mapM;

public:
    void add(std::list<std::string>& values)
    {
        if (values.empty()) // sanity check
            return;

        std::string s(*(values.begin()));
        values.erase(values.begin());
        if (values.empty())
            return;

        MapIndex *mi = mapM[s];  // <- question about this line
        if (!mi)
            mi = new MapIndex();
        mi->add(values);
    }
}
Run Code Online (Sandbox Code Playgroud)

我关注的主要问题是,如果将新项目添加到地图中,mapM [s]表达式是否会返回对NULL指针的引用?

SGI文档这样说:DATA_TYPE&运算符[](常量为key_type&K)返回到与特定键相关联的对象的引用.如果映射尚未包含此类对象,则operator []将插入默认对象data_type().

所以,我的问题是插入默认对象data_type()是否会创建一个NULL指针,还是会创建指向内存中某处的无效指针?

Meh*_*ari 23

它会创建一个NULL(0)指针,无论如何这是一个无效的指针:)

  • C++ Standard,8.5第5段:'默认初始化T类型的对象意味着:否则(既不是非POD也不是数组),该对象是零初始化的.上面几行:'要初始化T类型的对象意味着:如果T是标量类型(3.9),则将对象设置为0(零)转换为T的值;' 在同一标准中,3.9,第10段:'算术类型(3.9.1),枚举类型,指针类型和指向成员类型的指针(3.9.2),[...]统称为标量类型.所以是的,指针将默认初始化为0. (21认同)
  • 我不介意它是无效的,但希望它是"安全的".您可以轻松检查0指针,并可以在其上调用"删除".有关此内容的任何参考(URL)? (6认同)

Jam*_*ook 18

是的,它应该是一个零(NULL)指针,因为stl容器将在未明确存储时默认初始化对象(即在您正在执行时访问地图中的非存在键或将矢量调整为更大的大小).

C++标准,8.5第5段规定:

默认初始化T类型的对象意味着:

  • 如果T是非POD类类型(子句类),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的)
  • 如果T是数组类型,则每个元素都是默认初始化的
  • 否则,对象的存储空间被初始化.

您还应该注意,默认初始化与简单地省略构造函数不同.省略构造函数并简单地声明一个简单类型时,您将获得一个不确定的值.

int a; // not default constructed, will have random data 
int b = int(); // will be initialised to zero
Run Code Online (Sandbox Code Playgroud)


Mil*_*kov 5

更新:我完成了我的程序,我所询问的那一行有时会导致它崩溃,但会在稍后阶段发生。问题是我正在创建一个新对象而不更改存储在 std::map 中的指针。真正需要的是引用或指向该指针的指针。

MapIndex *mi = mapM[s];  // <- question about this line
if (!mi)
    mi = new MapIndex();
mi->add(values);
Run Code Online (Sandbox Code Playgroud)

应改为:

MapIndex* &mi = mapM[s];  // <- question about this line
if (!mi)
    mi = new MapIndex();
mi->add(values);
Run Code Online (Sandbox Code Playgroud)

我很惊讶没有人注意到这一点。