2013-09-11 3 views
0

Мне было интересно, был ли способ поместить объект после создания экземпляра. Скажем, объект экземпляра от класса Foo с ниже реализации:Как правильно разместить объект после создания без изменения объявления класса?

class Foo 
{ 
    size_t addr; 
    unsigned allocationNum; 

public: 
    Foo() 
    { 
     addr = (size_t)this; 
     allocationNum = 0; 
    } 

    ~Foo() 
    { 
     addr = 0; 
     allocationNum = 0; 
    } 

    void SetAllocNum(unsigned nAllocationNum) 
    { 
     allocationNum = nAllocationNum; 
    } 

    unsigned GetAllocNum() const 
    { 
     return allocationNum; 
    } 

    size_t GetAddress() const 
    { 
     return addr; 
    } 
}; 

экземпляр объекта, то создается через Foo* object = new Foo();. Есть ли способ сказать, добавить объект, чтобы (size_t)object или sizeof(*object) показал это как более крупный объект? Также, когда вы говорите, что для этого объекта используется стандартный тип данных, например char *, есть способ сделать это, чтобы заставить char * соответствовать размеру объекта, на который он набрасывается? Я задаю эти вопросы несколько из любопытства и потому, что я чувствую, что это может решить проблему, которая у меня есть с моей программой. Вот конкретный контекст:

T* AddObject() 
{ 
    T* object = new T(); // Here is the new object T=Foo in this case. 
    *(T*)(buffer+position) = *object; // Being stored in a char* buffer at current empty position 
    T* returnValue = &(*(reinterpret_cast<T*>(buffer+position))); 
    //^Here I try casting the char* [email protected] with the object contents stored inside the buffer. 
    return returnValue; 
} 

Проблема с этим состоит в том, что он бросает его на объект T несколько прилично, но размер по-прежнему, что из буфера. Выполнение sizeof(*object) в основном будет показывать то, что я думаю, что размер объекта должен быть, но если сравнить с (size_t) object из Foo* object = new Foo() с (size_t)differentObj от Foo* differentObj = AddObject()(size_t)differentObj будут таким же, как (size_t)buffer, но не таким же, как (size_t)object. Может быть, потому, что я не понимаю, что size_t представляет иначе, чем sizeof, независимо от того, имеет ли количество бит объекты в памяти или нет. Я не уверен. По крайней мере, из того, что я понимаю, sizeof представляет объем памяти в байтах, который занимает переменная или тип.

+0

Является ли это вашей идеей о том, как сериализовать объекты в/из буферов памяти и, в конечном итоге, (потенциально) через/другие среды? Я спрашиваю, потому что (а) есть * много * лучших способов и (б) Если вы заинтересованы в создании объекта в буфере самоконтролируемой памяти, я предлагаю вам изучить [место-новую идиому] (http://stackoverflow.com/questions/222557/what-uses-are-there-for-placement-new). Несмотря на это, объекты определяются по типу с определенным статическим размером. Вы не можете изменить это определение во время выполнения. Но вы можете содержать членов, которые используют управление кучей для роста (например: вектор). – WhozCraig

+0

@WhozCraig хорошо Я попытался сделать сериализацию через Boost, но проблема с boost была необходимостью управления объявлением объекта, чтобы дать доступ для повышения сериализации. Атм. Я не могу коснуться, где объявлена ​​/ определена декларация объекта, поэтому мне пришлось придумать это обходное решение. Плюс я предпочитаю использовать векторы для реализации контейнеров, но мне было запрещено делать это в этой программе. Спасибо, потому что вы и другие предложения помогли мне указать на правильное направление. Также я не мог избежать отправки указателя объекта, поэтому сериализация не помогла бы мне в этом случае? – hellfiremarine

ответ

0

Если вы хотите построить объект по определенному адресу, вы должны использовать размещение нового:

T* AddObject() 
{ 
    return new (buffer+position) T(); 
} 

Обратите внимание, что вы не можете использовать по умолчанию удалить, если вы используете эту версию new.

sizeof - оператор времени компиляции, который даст свое значение от типа. Он не может быть перегружен, а возвращаемое значение имеет тип size_t. size_t - целочисленный тип без знака, определенный в стандартной библиотеке.

При написании (size_t)differentObj вы передали от T* по номеру size_t. Это действительно, но обычно это не то, что хотелось бы сделать. Если вы хотите рассчитать смещение между двумя указателями в точных байтах, вы скажете reinterpret_cast<char*>(pointer1) - reinterpret_cast<char*>(pointer2).

Если два указателя имеют одинаковое значение (например, (size_t)differentObj == (size_t)buffer), это означает, что они указывают на один и тот же объект. (Это означает, что в вашем примере position должно быть установлено в 0).

В любом случае, вы должны использовать эти методы только в том случае, если вам действительно нужно, потому что вождение указателя сильно усложняет код.

+0

спасибо! Новое занятие работало для решения проблемы, которую я имел. Обычно я предпочитаю использовать оператор sizeof() при сравнении объектов, но я был ограничен в этой программе для использования (size_t). Также мне нравится использовать более надежные контейнеры STL для хранения контейнеров, такие как векторы, но ограничено использованием буфера char * для хранения объектов. Плюс я бы поднял полезность этого ответа, но у меня недостаточно репутации на этом форуме, но для этого. – hellfiremarine

1

Вы понимаете, что (size_t)object не дает вам никакого размера, но что это (c-style) листинг объекта для типа size_t (обычно определяется как unsigned int)? См. это size_t documentation. sizeof (см., Например, its documentation here) возвращает значение типа size_t, возможно, именно здесь ваше замешательство?

Возможно, вы все равно хотите использовать sizeof. Однако будьте осторожны с тем, что вы проходите до sizeof. sizeof(Foo*), например, даст вам размер указателя на Foo, а не на размер объекта Foo. Для последнего вам нужно будет использовать sizeof(Foo).

(sizeof)x оценивается во время компиляции и рассчитывается с помощью определения типа; в случае, если x является определяемым пользователем типом, то есть интерфейсом структуры или класса. Таким образом, нет возможности изменить результат sizeof, кроме изменения интерфейса.

+0

спасибо! В этом сценарии я предпочел бы использовать sizeof для определения размера объектов, но люди, которые написали код для тестирования используемого контейнера (size_t), и поэтому я пытался выяснить, что представляет объект (size_t). Ваши предложения дали мне больше информации о size_t. Я бы сказал, что ответ полезен, но в настоящее время у меня недостаточно отзывов на этом форуме. – hellfiremarine

Смежные вопросы