如何在C++中续订对象

How to renew an object in C++

本文关键字:对象 C++      更新时间:2023-10-16

我有以下代码:

   vector<SomeClass> objs;
   SomeClass obj;  // create a new obj with a new name
   objs.push_back(obj);
   while (someConditionIsTrue()){
       use(&obj);
       obj = new SomeClass(); // create a new obj with an existing name
       objs.pushback(obj)
   }

在这段代码中,new SomeClass();是java OOP形式的,而不是c++代码。应该使用什么代码而不是obj = new SomeClass();

答案是:

obj = SomeClass();

new SomeClass()将返回指向SomeClass对象的指针。不能将其分配给变量obj,该类型为SomeClass,而不是SomeClass*

编辑:如果我记得很清楚的话,SomeClass obj();也应该起作用。

我想你想要的是这样的东西:

vector<SomeClass *> objs;
SomeClass* obj = new SomeClass;  // create a new obj with a new name
objs.push_back(obj);
while (someConditionIsTrue())
{
  use(&obj);
  obj = new SomeClass; // create a new obj with an existing name
  objs.push_back(obj)
}

您对该语言的理解有些偏离

vector<SomeClass> objs;
SomeClass obj;  // create a new obj with a new name
objs.push_back(obj);
while (someConditionIsTrue()){
    use(&obj);
    obj = new SomeClass(); // create a new obj with an existing name
    objs.pushback(obj)
 }

以下是实际发生的情况

// create an object called "objs" which is a std::vector header, on the stack.
vector<SomeClass> objs;
// create an instace of "SomeClass" on the stack, call it obj.
SomeClass obj;
// allocate storage in the heap for some number of SomeClass instances to
// act as the storage for "objs", and assign them to it's "m_data" member.
// default construct the first one,
// then call it's copy constructor with the stack instance of "Obj" to
// copy the values/data into the first entry of the heap allocation of objs. 
objs.push_back(obj);
while (someConditionIsTrue()){
   // pass a pointer to the stack-allocated instance of obj.
   use(&obj);
   // create a new instance of "SomeClass" on the heap,
   // default/zero construct it,
   // return the pointer to this heap allocation and pass it
   // to obj.operator=(const SomeClass*) to copy the data into
   // the stack space allocated for "obj".
   obj = new SomeClass(); // create a new obj with an existing name
   // leak the pointer to the previous heap allocation by not storing it.
   // increase the size of the heap allocation backing objs and then
   // default construct the first SomeClass instance in the new space,
   // then copy our freshly copy-initialized stack instance back into it.
   objs.pushback(obj)
}

你可以用许多其他方式编写这段代码,但似乎最明智的方法是

std::vector<SomeClass> objs;
while (someConditionIsTrue()) {
    objs.resize(objs.size() + 1); // grow me a new element.
    use(&objs.back());
}

或者让"使用"取一个参考。

void use(SomeClass& obj);
//...
    use(objs.back());

如果您真的想要一个本地对象来尝试该条目。

while (someConditionIsTrue()) {
    objs.resize(objs.size() + 1);
    // the compiler will either optimize this out entirely,
    // or use a pointer under the hood.
    SomeClass& obj = objs.back();
    use(&obj); // take the address of the object obj references.
}

此外,请注意"resize()"可能会变得昂贵。你可能想提前做这件事:

objs.reserve(1024); // or something you know is likely to cover most use cases.

如果你真的,真的必须使用指针。

SomeClass* obj = nullptr;
while (someConditionIsTrue()) {
    objs.resize(objs.size() + 1);
    obj = &objs.back();
    use(obj);
}

代替"objs.resize()",您可以将placementnew与ctor:一起使用

    objs.emplace_back(SomeClass());

其他人建议你使用

obj = Someclass();

但请注意,这是在复制对象的默认构造堆栈副本。

{
    SomeClass tempObj;
    obj.operator=(std::move(tempObj));
}

我不认为这是你真正想做的。这比拥有一个像这样的堆栈本地副本更昂贵:

while (someCondition()) {
    SomeClass stackCopy;
    ...
}

编译器足够聪明,不会在每个循环中放弃堆栈空间。它将做一件叫做"Placementnew"的事情,在同一个对象上重新调用构造函数:

SomeClass obj;
while (someCondition()) {
     new (&obj) SomeClass(); // Call SomeClass() ctor on the memory at &obj
     ...
}

但是,这基本上就是编译器实现我之前的代码示例的方式。