我们有一个基类A,B类派生自A. 现在,使用placement new运算符分配B类。 作为我的代码的一部分,我在类A中添加了类C
现在,placement new只使用了sizeof类的malloc,并没有考虑C类。 在B类构造函数中调用C类构造函数。 (这是我的怀疑)
我想知道这是否正确。或者我们是否在展示位置新分配中添加了C类的大小? 如果我们将内存加起来,我们如何调用C类的构造函数,它会再次分配内存?
card.h {
class Card
{
private:
char hwModel; // HW/FW model and rev are stored in the
// database to detect change of card type
char hwRev;
char serialNum[EM_CARD_SERIAL_NUM_SIZE];
char fwModel;
char fwRev;
>>>>
public:
class IssuResource *ptrIssuResrc;
void *operator new(size_t size, void *objP) {size = size; return objP;};
// overload the new operator
void operator delete(void *objP) { objP = objP;};
// overload the delete operator
Card();
}
chopperCard.cpp
// Allocate Memory and Create Card Object
/* sa_ignore */
buf = (UINT32 *)malloc(sizeof(CardChop));
if (buf == NULL) {
emLogError(EM_INTERNAL_ERROR, __FUNCTION__,
"exit: failed to allocate %d bytes for card object\n",
sizeof(CardChop)
);
exit(1);
}
/* sa_ignore */
card = new (buf) CardChop(spa_issu_restart); --> placement new
}
Constructor for choppercard:
{
CardChop::CardChop (boolean is_issu_set) : Card()
{
issu_inprogress = is_issu_set;
if (is_issu_set) {
ISSUTRACE(4,"Issu state is SET\n");
dev_np37xx_update_issu_state(is_issu_set);
dev_set_issu_state(is_issu_set);
dev_dm_issu_state(is_issu_set);
dev_tigris_issu_state(is_issu_set);
dev_evros_issu_state(is_issu_set);
dev_evros1_issu_state(is_issu_set);
>>>
vtwin->fvt->set_gp_stat(vtwin, VTWIN_GP_STAT_APP_TRACE1,
CHOP_BG_INIT_FAIL);
// init Bourget device
initDevice((dev_object_t *)bourget);
vtwin->fvt->set_gp_stat(vtwin, VTWIN_GP_STAT_APP_TRACE1, CHOP_BG_INIT_AFTER);
ptrIssuResrc = new IssuResource();
}
答案 0 :(得分:1)
Placement new将像operator new
一样无需放置,除了它使用提供的地址而不是从堆分配。既然operator new
的形式都不会调用实际的构造函数,那么构造完全相同 - 编译器调用对象构造函数就像这样
T *p = new T;
变为(语法无效,T::operator new
可能变为::operator new
):
T *p = T::operator new(sizeof(T)); p->T();
有了展示位置,它几乎相同:
T *p = new(somewhere) T;
成为(无效,如上所述):
T *p = T::operator new(sizeof(T), somewhere); p->T();
如果你有这样的事情:
class C { ... };
class A
{
...
C c;
};
class B: public A
{
...
}
然后在调用B的构造函数时自动调用C的构造函数。 (而B的构造函数会自动调用A的构造函数)
答案 1 :(得分:0)
sizeof
返回的值包括所有基数和成员的大小。没有其他大小的概念可以混淆事物。
看起来代码过于复杂。您使用malloc
所做的只是重新发明new
的默认行为。
这也是一样,但更简单:
card = new CardChop(spa_issu_restart);
if (card == NULL) {
emLogError(EM_INTERNAL_ERROR, __FUNCTION__,
"exit: failed to allocate %d bytes for card object\n",
sizeof(CardChop)
);
exit(1);
}
如果使用全局默认operator new
,您还应该删除operator delete
重载。
事实上,放置新内容的最佳做法是根本不使用delete
。 (请注意,您已将operator delete
定义为什么都不做。)更好的方法是使用伪析构函数调用,它看起来像
card_ptr->~CardChop(); // execute destructor but no delete
free( card_ptr ); // release placement memory a la delete
另外,请注意exit
是一种可能不安全的终止程序的方法,因为它不会破坏本地对象。考虑抛出异常。