1

単純な古い Cを使用する場合、次のように実装されるデータ型があります

typedef struct {
    ...many other members here...
    unsigned short _size;
    char           _buf[0];
} my_data; 

私がやりたいのは、基本的にそれをクラスにして、 lessequalitycopy constructoroperator assignmentなどの通常の演算子を追加することです。ご想像のとおり、 std::mapなどの連想コンテナーでそのようなクラスをkeyとして使用します。

バッファは理想的にはオブジェクト自体と同じレベルにある必要があります。そうしないと、2 つのバッファ (バッファ) を比較する必要があるときに、CPU がポインタを取得してメモリにロードする必要があります。割り当てられたメモリが残りのデータメンバーと連続していないため、std::vectorを使用したくありません。

私にとっての主な問題は、バッファのサイズが適切なメモリサイズを割り当てる関数がCにあるという事実です。C++ では、そのようなことはできません。

私は正しいですか?乾杯

4

3 に答える 3

1

これはまったく不可能です。オブジェクトは事実上可変サイズですが、std::mapは常に固定サイズとして扱い、コピーや移動を実装する方法はありません。このようなハックを使用するには、古い C スタイルのコンテナーが必要になります。

編集:カスタムアロケーター。興味深い解決策、私はそれを考えていませんでした。あなたがそれを機能させることができるかどうかはわかりませんが、検討する価値はあります。

于 2012-08-10T07:48:21.527 に答える
0

C++では次のようにアプローチできます。

struct MyData {
    unsigned short size_;
    char * buf () { return reinterpret_cast<char *>(&size_ + 1); }
    //...
};

new演算子をオーバーロードして、を使用mallocし、deleteを使用してfree、オンデマンドでデータ構造を拡張できるようにする必要がありますrealloc

DeadMGが指摘しているように、これはSTLコンテナで簡単に使用することはできません。MyData1つのアプローチは、コンテナー内でへのポインターを使用することです。もう1つは、のカスタムスマートポインタラッパークラスですMyData

編集:MyDataこれは一種のスマートポインターとして機能するハックですが、インテリジェンスはによって管理されvectorます。

struct MyData {
    struct State {
        unsigned short size_;
        //...
    };
    std::vector<State> data_;
    MyData () {};
    MyData (unsigned short size)
        : data_(1 + size/sizeof(State) + !!size%sizeof(State)) {
        data_[0].size_ = size;
    }
    unsigned short size () const { return data_[0].size_; }
    //...
    char * buf () { return reinterpret_cast<char *>(&data_[1]); }
};
于 2012-08-10T07:46:14.257 に答える
0

いいえ、できません。長さゼロの配列は正当な C++ ではありません。

長さ1の配列で非常に似たようなことを行うことができますが、インスタンスの作成を自分で管理する必要があるため、コピー コンストラクターやオブジェクトを に格納する必要はありませんstd::map

おそらく次のようなものです:

class my_data {
public:
  static my_data* create(int size) {
    void* memory = malloc(sizeof(_size) + size);
    return new(memory) my_data(size);
  }

  static void destroy(my_data* ptr) {
    ptr->~my_data();
    free(ptr);
  }

private:
  //disable construction and destruction except by static methods above
  explicit my_data(int size) : _size(size) {}
  ~my_data(){}

  //disable copying
  my_data(const my_data&);
  my_data& operator=(const my_data&);

  unsigned short _size;
  char           _buf[1];
};

デフォルトのコンストラクタ、デストラクタ、コピー コンストラクタ、および代入演算子はすべてプライベートであるため、クラスの使用方法が大幅に制限されることに注意してください。


1実際には、標準に準拠していませんが、ほぼすべての場所で機能します。

于 2012-08-10T07:55:21.840 に答える