0

C言語の外部APIライブラリの構造体Fooがあり、その上にC++インターフェースを書いています。

だから私はこのようなクラスを持っています:

class ClassFoo
{
public:
    ClassFoo(const Foo * ptr) : ptr(ptr) { }
    ~ClassFoo();

    bool method1();
    int method2();
    ... (other methods)
private:
    const Foo * ptr;
}

次に、外部ライブラリは、s のstruct Barコレクション、Foofoo の数を取得するためのメソッド、およびFoo*ポインターの配列を取得するためのメソッドである別のものを定義します。

int APIbarGetNumFoos(const Bar* ref);
void APIbarGetFoos(const Bar* ref, int maxSize, const Foo* foos[]);

私は次のように定義しますClassBar

class ClassBar
{
public:
    ClassBar(const Bar * ptr) : ptr(ptr) { }
    ~ClassBar();

    std::vector<ClassFoo> getFoos();

    ... (other methods)
private:
    const Bar * ptr;
}

Foo*ここで問題: メモリと速度の効率を高めるために、配列を割り当てて C API を呼び出し、すべてを結果ベクトルにコピーすることを避けたいと考えています。

C ++は、ClassFooインスタンスにポインターのみが含まれているFoo*こと、およびそのサイズがポインターのサイズであることを保証しますか?(vtablesを回避するために)仮想メソッドを使用しない場合、次のように定義できますgetFoos():

std::vector<ClassFoo> ClassBar::getFoos()
{
    int size = APIbarGetNumFoos(ptr);
    std::vector<ClassFoo> result(size);
    APIbarGetFoos(ptr, size, (const Foo**) &result[0]);
    return result;
}

言い換えると、 の配列が の配列とClassFoo厳密に同じメモリ内にあると確信できFoo*ますか?

ありがとう!

エティエンヌ

4

3 に答える 3

3

static_assert を使用できます。

static_assert(sizeof(Foo*) == sizeof(ClassFoo), "Sizes don't match!");

サイズが一致しない場合、コンパイル時にエラーが発生します。純粋主義者は、これはまだ十分に厳密ではないと言うかもしれませんが、実際にはおそらく問題ありません。

ちなみにこちら:

(const Foo*) &result[0]

私はあなたが意味するかもしれないと思う:

reinterpret_cast<const Foo**>(&result[0]);
于 2013-05-30T11:00:06.953 に答える
1

簡単な答えは次のとおりだと思います。はい!

C++ オブジェクト (vtable を含まない) は C 構造体に似ており、メソッドは暗黙的なパラメーターを持つ C 関数に似ていthisます。

ただし、RTTI が有効になっている場合、それが正しいかどうかはわかりません。

于 2013-05-30T11:00:35.537 に答える
0

回答とコメントから、次のように見えます。

  • 最近の gcc (4.8) で動作し、メイン コンパイラで動作するようです
  • 以下を使用してコンパイル時にこれを保証できます: (gcc 4.8でテスト済み)

    static_assert(! std::is_pod<ClassFoo>::value, "Foo* cannot be copied to ClassFoo");

  • 制限が少なく、is_standard_layout代わりに使用しても問題ないかもしれませんis_pod

于 2013-05-30T13:40:20.897 に答える