Назовите деструктор и затем конструктора (сбрасывающий объект)

Едва ли. GUID более централен Microsoft, тогда как UUID используется более широко (например, как в urn:uuid: схема URN, и в CORBA).

24
задан Unihedron 10 August 2014 в 14:24
поделиться

8 ответов

Don't get sucked in by the FQA troll. As usual he gets the facts wrong.

You can certainly call the destructor directly, for all objects whether they are created with placement new or not. Ugly is in the eye of the beholder, it is indeed rarely needed, but the only hard fact is that both memory allocation and object creation must be balanced.

"Regular" new/delete simplifies this a bit by tying memory allocation and object creation together, and stack allocation simplifies it even further by doing both for you.

However, the following is perfectly legal:

int foo() {
    CBar bar;
    (&bar)->~CBar();
    new (&bar) CBar(42);
 }

Both objects are destroyed, and the stack memory is automatically recycled too. yet unlike the FQA claims, the first call of the destructor is not preceded by placement new.

29
ответ дан 28 November 2019 в 22:13
поделиться

Почему бы не реализовать метод Clear (), который делает то же, что и код в теле деструктора? Затем деструктор просто вызывает Clear (), а вы вызываете Clear () непосредственно для объекта, чтобы «сбросить его».

Другой вариант, предполагая, что ваш класс правильно поддерживает присваивание:

MyClass a;
...
a = MyClass();

Я использую этот шаблон для сброса std :: stack экземпляров, как это делает адаптер стека не обеспечивают четкой функции.

20
ответ дан 28 November 2019 в 22:13
поделиться

Вы не можете вызвать конструктор указанным вами способом. Вместо этого вы можете сделать это с помощью place-new (как указано в вашем коде):

new (anObject) AnObject();

Этот код гарантированно будет четко определен, если ячейка памяти все еще доступна - как и должно быть в вашем случае.

( Я удалил часть о том, является ли это спорным кодом или нет - он четко определен. Точка.)

Между прочим, Брок прав: как реализация delete не исправлена - это не то же самое, что вызов деструктора, за которым следует free . Всегда объединяйте вызовы new и delete , никогда не смешивайте один с другим: это undefined.

9
ответ дан 28 November 2019 в 22:13
поделиться

Technically it is bad practice to call constructors or destructors explicitly.

The delete keyword ends up calling them when you use it. Same goes for new with constructors.

I'm sorry but that code makes me want to tear my hair out. You should be doing it like this:

Allocate a new instance of an object

AnObject* anObject = new AnObject();

Delete an instance of an object

delete anObject;

NEVER do this:

anObject->~AnObject(); // My step 1.
free(anObject)

If you must "reset" an object, either create a method which clears all the instance variables inside, or what I would recommend you do is Delete the object and allocate yourself a new one.

"It is the core of the language?"

That means nothing. Perl has about six ways to write a for loop. Just because you CAN do things in a language because they are supported does mean you should use them. Heck I could write all my code using for switch statements because the "Core" of the language supports them. Doesn't make it a good idea.

Why are you using malloc when you clearly don't have to. Malloc is a C method.

New and Delete are your friends in C++

"Resetting" an Object

myObject.Reset();

There you go. This way saves you from needlessly allocating and deallocating memory in a dangerous fashion. Write your Reset() method to clear the value of all objects inside your class.

14
ответ дан 28 November 2019 в 22:13
поделиться

Вы не можете вызвать конструктор таким образом, но нет ничего плохого в повторном использовании памяти и вызове нового размещения, пока вы не удаляете или освобождаете (освобождаете ) память. Я должен сказать, что переустановка такого объекта немного схематична. Я бы написал объект, который можно явно сбросить, или написать метод подкачки и использовать его для его сброса.

Например,

anObject.swap( AnObject() ); // swap with "clean" object
4
ответ дан 28 November 2019 в 22:13
поделиться

Если ваш объект имеет разумную семантику присваивания (и правильный оператор =), тогда * anObject = AnObject () имеет больше смысла и его легче понять.

3
ответ дан 28 November 2019 в 22:13
поделиться

It is far better just to add something like a Reset() method to your object rather than play with placement new's.

You are exploiting the placement new feature which is intended to allow you to control where an object is allocated. This is typically only an issue if your hardware has "special" memory like a flash chip. IF you want to put some objects in the flash chip, you can use this technique. The reason that it allows you to explicitly call the destructor is that YOU are now in control of the memory, so the C++ compiler doesn't know how to do the deallocation part of the delete.

It is not saving you much code either, with a reset method, you will have to set the members to their starting values. malloc() doesn't do that so you are going to have to write that code in the constructor anyway. Just make a function that sets your members to the starting values, call it Reset() call it from the constructor and also from anywhere else you need.

1
ответ дан 28 November 2019 в 22:13
поделиться

Note that they're not malloc and free that are used, but operator new and operator delete. Also, unlike your code, by using new you're guaranteeing exception safety. The nearly equivalent code would be the following.

AnObject* anObject = ::operator new(sizeof(AnObject));
try
{
    anObject = new (anObject) AnObject();
}
catch (...)
{
    ::operator delete(anObject);
    throw;
}

anObject->~AnObject();
::operator delete(anObject)

The reset you're proposing is valid, but not idiomatic. It's difficult to get right and as such is generally frowned upon and discouraged.

7
ответ дан 28 November 2019 в 22:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: