Я понимаю, что размещение новых вызовов обычно сопровождается явным вызовом деструктора. Если мне не нужно деструктор (нет кода для ввода там и нет переменных-членов, у которых есть деструкторы), могу ли я безопасно пропустить явный вызов деструктора?
Да. Если мне не нужно лететь в Нью-Йорк, прежде чем отправлять этот ответ, могу ли я спокойно пропустить поездку? :) Однако, если деструктор действительно не нужен, потому что он ничего не делает, то какой вред там при вызове?
Если компилятор может определить, что деструктор должен быть не-op, я бы ожидал, что он устранит этот вызов. Если вы не пишете явный dtor, помните, что ваш класс все еще имеет dtor, и интересный случай - здесь - это то, что язык вызывает тривиальным.
Решение: уничтожить ранее построенные объекты, прежде чем строить над ними, даже если вы считаете, что dtor не является оператором.
Я хочу написать привязки C++ для C API. В API C многие объекты доступны только указателем. Вместо создания объекта-обертки, который содержит один указатель (который расточительный и семантически запутанный). Я хочу использовать новое размещение для создания объекта по адресу объекта C.
Это назначение классов, совместимых с макетами, и reinterpret_cast. Включите статическое утверждение (например, макрос Boost, 0x static_assert и т. Д.), Проверяя размер и/или выравнивание, как вы пожелаете, для короткой проверки работоспособности, но в конечном итоге вам нужно немного узнать, как ваша реализация определяет классы. Большинство из них обеспечивают прагмы (или другие механизмы, связанные с реализацией), чтобы контролировать это, если это необходимо.
Самый простой способ, чтобы содержать C-структуру в пределах типа C++:
// in C header
typedef struct {
int n;
//...
} C_A;
C_A* C_get_a();
// your C++
struct A {
void blah(int n) {
_data.num += n;
}
// convenience functions
static A* from(C_A *p) {
return reinterpret_cast<A*>(p);
}
static A const* from(C_A const *p) {
return reinterpret_cast<A const*>(p);
}
private:
C_A _data; // the only data member
};
void example() {
A *p = A::from(C_get_a());
p->blah(42);
}
Я хотел бы сохранить такие преобразования инкапсулируются, а не посыпая reinterpret_casts повсюду, и многое другое равномерное (т. е. сравнение сайта вызова для const и не const), следовательно, функции удобства. Также немного сложнее изменить класс, не заметив, что этот тип использования все равно должен поддерживаться.
В зависимости от конкретного класса вы можете сделать этот элемент данных общедоступным.
Вы имеете в виду собственно называть деструктора себя в коде? Вы должны (почти) НИКОГДА не делать этого. – Falmarri
Размещение новое является одним из тех редких случаев, когда вы должны. –
@ Джош: Я не думаю, что понимаю проблему. Почему бы не создать объект C как единственный элемент данных вашего объекта C++? Затем в ваших функциях-членах передайте указатель на этот член в функцию API C, которую вы делегируете. –