C++ class 构造函数清除映射

C++ class constructor clears map

我的第一个构造函数编辑一个成员 std::map,然后调用另一个构造函数。在第一个构造函数的末尾,地图的大小为 2,在第二个构造函数的开头为 0。这是什么原因造成的?

这是我的头文件:

// Test.h
#include <map>
#include <string>

class Test
{
public:
    Test(std::string name, int age);
private:
    Test();

    std::map<std::string, int> myMap_;
}

这是我的代码:

// Test.cpp
#include "test.h"

Test::Test()
{
    std::cout << myMap_.size() << std::endl; // Outputs 0
}

Test::Test(std::string name, int age)
{
    myMap_.insert(name, age);
    myMap_.insert("test", 6);

    std::cout << myMap_.size() << std::endl; // Outputs 2
    Test();
}

编辑: 这是我的主要功能:

#include "test.h"

int main()
{
    Test t("yo", 4);
    return 0;
}

第二个构造函数插入 2 个元素。所以大小是2.

第一个构造函数没有插入任何元素。所以大小为0.


我想也许您希望第二个构造函数中的 Test(); 对同一对象 "call the other constructor"。然而,这不会发生。构造函数不同于常规函数。

代码Test();实际上是创建一个Test类型的临时对象,通过调用默认构造函数进行初始化。然后该对象立即被销毁,因为它是临时的。

构造函数没有名称,就名称查找而言,不可能像常规函数那样调用它们。相反,当您提供创建对象的语法时,它们会被调用。

如果你想拥有一些由多个构造函数共享的公共代码;您可以将该代码放在由多个构造函数调用的函数中,或者使用 delegating constructors 功能。在后一种情况下,委托必须在构造函数体内的任何语句执行之前发生。

您实际上并不是在同一个对象上调用构造函数,而是创建了一个临时的新对象,该对象没有名称。看成这样:

Test::Test(std::string name, int age)
{
    myMap_.insert(name, age);
    myMap_.insert("test", 6);

    std::cout << myMap_.size() << std::endl; // Outputs 2
    Test other = Test(); //you create a new object here
}

在 C++11 中,你可以做一些你想做的事情(这称为构造函数委托):

Test::Test(std::string name, int age)
:Test()
{
    myMap_.insert(name, age);
    myMap_.insert("test", 6);

    std::cout << myMap_.size() << std::endl;
}

这里的不同之处在于 Test() 构造函数将在地图上的插入操作之前被调用。

您正在创建一个测试的两个实例。

Test 的第一个实例使用姓名和年龄构造,将元素插入其 myMap_,但第二个实例没有。

当您在 Test(name, age) 构造函数中调用 Test() 它正在使用 Test() 构造函数在本地创建第二个测试实例 不插入地图。第二个实例几乎会立即被销毁(因为它没有分配给任何东西)。

我认为您正试图在同一个对象上使用两个构造函数,但这仅适用于 inheriting 对象,其中每个派生都需要调用自己的构造函数并调用其基地.

您可以创建一个函数并调用它:

// Test.h
#include <map>
#include <string>

class Test
{
public:
    Test(std::string name, int age);
    void OutputSize();

private:
    Test();

    std::map<std::string, int> myMap_;
}

Test::Test(std::string name, int age)
{
    myMap_.insert(name, age);
    myMap_.insert("test", 6);

    OutputSize();
}

void Test::OutputName()
{
   std::cout << myMap_.size() << std::endl; // Outputs 2
}