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* buffer@position with the object contents stored inside the buffer.
   return returnValue;
}

これの問題は、それを T オブジェクトにある程度適切にキャストしていることですが、サイズは依然としてバッファーのサイズのままです。main で実行sizeof(*object)すると、オブジェクトのサイズがどうあるべきかが表示されますが、(size_t) object from Foo* object = new Foo()と from を比較すると、(size_t)differentObj from Foo* differentObj = AddObject()(size_t)differentObj と同じです(size_t)bufferが、同じではありません(size_t)object。たぶん、メモリ内のオブジェクトが持っているビット数とはsize_t異なる表現を理解していないためかもしれません。sizeof少なくとも私が理解していることからsizeof、変数または型が占有するメモリの量をバイト単位で表しています。

4

2 に答える 2

1

(size_t)objectそれはサイズを与えていませんが、これはオブジェクトの型size_t(通常は unsigned int として定義されます) への (c スタイルの) キャストであることを認識していますか? たとえば、このsize_t documentationを参照してください。sizeof(たとえば、そのドキュメントを参照してください) type の値を返しますsize_t。おそらく、それについての混乱がどこから来ているのでしょうか?

sizeofずっと使いたくなるはずです。ただし、に渡すものには注意してくださいsizeofsizeof(Foo*)たとえばFoo、オブジェクトのサイズではなく、へのポインターのサイズが得られFooます。後者の場合は、を使用する必要がありますsizeof(Foo)

(sizeof)xコンパイル時に評価され、型定義を介して計算されます。ユーザー定義型の場合x、つまり構造体またはクラス インターフェイスによるものです。sizeofしたがって、インターフェイスを変更する以外に、 の結果を変更する方法はありません。

于 2013-09-11T08:04:12.970 に答える
0

特定のアドレスにオブジェクトを構築したい場合は、placement new を使用する必要があります。

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

このバージョンの を使用する場合は、デフォルトの削除を使用できないことに注意してくださいnew

sizeof型から値を生成するコンパイル時の演算子です。オーバーロードできず、戻り値の型はsize_tです。size_t標準ライブラリで定義されている符号なし整数型です。

書くときは from to に(size_t)differentObjキャストします。これは有効ですが、通常はやりたいことではありません。正確なバイト単位で 2 つのポインター間のオフセットを計算する場合は、.T*size_treinterpret_cast<char*>(pointer1) - reinterpret_cast<char*>(pointer2)

2 つのポインターが同じ値 (例: (size_t)differentObj == (size_t)buffer) を持つ場合、それらは同じオブジェクトを指していることを意味します。(これは、例でpositionはに設定する必要があることを意味0します。)

とにかく、これらの手法は本当に必要な場合にのみ使用してください。ポインターをいじるとコードが非常に複雑になるためです。

于 2013-09-11T08:39:17.053 に答える