c++类构造函数清除map

C++ class constructor clears map

本文关键字:map 清除 构造函数 c++      更新时间:2023-10-16

我的第一个构造函数编辑成员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();为同一个对象"调用另一个构造函数"。然而,这并没有发生。构造函数不同于普通函数。

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

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

如果你想让一些通用代码被多个构造函数共享;您可以将该代码放在由多个构造函数调用的函数中,或者使用委托构造函数特性。对于后一种情况,必须在执行构造函数体中的任何语句之前进行委托。

实际上并没有调用同一对象的构造函数,而是创建了一个临时的新构造函数,然后该构造函数没有名称。就像这样:

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的两个实例。

Test的第一个实例使用名字和年龄构造,在myMap_中插入元素,而第二个实例不这样做。

当你在Test(name, age)构造函数中调用Test()时,它正在使用不插入映射的Test()构造函数在本地创建第二个Test实例。这个第二个实例几乎会立即被销毁(因为它没有被赋值给任何对象)。

我认为你试图在同一个对象上使用两个构造函数,但这只适用于继承对象的,其中每个派生需要调用自己的构造函数并调用其基。

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

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