-2

我们有一个基类 A,B 类从 A 派生。现在 B 类是使用placement new 运算符分配的。作为我的代码的一部分,我在 A 类中添加了 C 类

现在placement new 只使用了B 类sizeof 的malloc,不考虑C 类。C 类构造函数在B 类构造函数内部调用。(这是我的嫌疑人)

我想知道那是否正确。还是我们在放置新分配中添加 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();
}
4

2 回答 2

1

新放置将像operator new没有放置一样工作,只是它使用提供的地址而不是从堆中分配。由于这两种形式的operator newwill 本身都不会调用实际的构造函数,因此无论哪种方式,构造都是完全相同的——编译器调用对象构造函数就像这样

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
{
  ...
}

那么C的构造函数会在B的构造函数被调用的时候被自动调用。(并且B的构造函数会自动调用A的构造函数)

于 2013-06-11T11:38:19.630 回答
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重载。


事实上,放置 new 的最佳做法是根本不使用delete。(请注意,您已定义operator delete什么都不做。)更好的方法是使用伪析构函数调用,看起来像

card_ptr->~CardChop(); // execute destructor but no delete
free( card_ptr ); // release placement memory a la delete

另外,请注意这exit是终止程序的潜在不安全方式,因为它不会破坏本地对象。考虑改为抛出异常。

于 2013-06-11T14:17:04.137 回答