C ++为什么在循环中创建对象时需要'new'

c++ why do i need 'new' when creating objects in a loop

本文关键字:new 创建对象 为什么 循环      更新时间:2023-10-16

我有一个程序,该程序读取看起来像这样的文件的行:

...
name1 (123)
name2 (345)
...

然后,它将每行作为 myclass 的对象存储在称为 namelist 的地图中。 namelist 的键是对象的名称,值为对象本身。在第一个版本中,代码 namelist 是类型 map<字符串,myClass> ,并且对象是在循环中以 myclass obj; (以及ofc all' ->'是'。'。'。,为什么?我读过您很少需要在C 中的对象上使用"新"。为什么我在这里需要它?

ifstream myfile ("input.txt");
map<string,MyClass*> namelist;
string line;
while ( getline(myfile,line) ) {
    istringstream iss(line);
    string word;
    while (iss>>word) {
        MyClass* obj = new MyClass;
        obj->name = word;
        iss>>word;
        sscanf(word.c_str(),"(%d)",&obj->number);
        namelist.insert( pair<string,MyClass*>(obj->name,obj) );
    }
}
myfile.close();

您不需要new。只需执行map<string,MyClass> namelistMyClass obj;(默认构造函数w/stack分配)

new用于在堆上分配对象,并且必须用delete明确处理数据。取而代之的是,只需使您的地图保存MyClass对象,而不是指向此类对象。地图对象将将对象复制到堆上,并为您处理DealLocation。。

您不需要new,因为std::map已经照顾了动态分配。

std::map<std::string, MyClass> namelist;

您甚至不需要首先创建一个临时变量,而是将其插入地图,从而创建一个不必要的副本。相反,在中直接创建对象将更有效。

以下技术要求MyClass仅具有默认构造函数。除了提高效率外,此技术还使您可以使用没有复制构造函数(例如g。g。 std::ifstream)作为地图值的类。

要获得与std::map::insert()相同的语义,需要向find()明确调用。如果您可以遵守地图中重复键覆盖现有对象的事实,则可以通过删除if来简化代码。

// Check if the key does not exist yet.                 
if (namelist.find(word) == namelist.end()){
    // Default-construct object within map and get a reference to it.
    MyClass& obj = namelist[word]; 
    // Do something with inserted obj...
    obj.name = word;
}

如果您的班级具有带有一个或多个参数的构造器,您想在现场施工期间致电,您需要C 11功能,即std::map::emplace()

// Construct MyClass within the map, if the key does not exist yet.                 
// Pass arguments arg1, arg2, argN to the constructor of MyClass.
auto res = namelist.emplace(arg1, arg2, argN);
if (res.second){ // new object inserted?
    // Get a reference to the inserted object.
    MyClass& obj = *res.first;
    // Do something with inserted obj...
    obj.name = word;
}