2009-09-07 11 views
6

私のアプリケーションは、多くの量のPandaオブジェクトを使用しています。各PandaにはBambooのオブジェクトのリストがあります。このリストは、Pandaが初期化されると変更されません(Bambooオブジェクトが追加または削除されません)。次のように現在、私のクラスが実装されています可変長オブジェクト:これまでは良いアイデアですか?

class Panda 
{ 
    int a; 
    int b; 
    int _bambooCount; 
    Bamboo* _bamboo; 

    Panda (int count, Bamboo* bamboo) 
    { 
    _bambooCount = count; 
    _bamboo = new Bamboo[count]; 

    // ... copy bamboo into the array ... 
    } 
} 

Bambooオブジェクトの配列を割り当てるのオーバーヘッドを軽減するために、以下のように、私はこのクラスを実装することができ - 基本的には、代わりに通常のコンストラクタを介してオブジェクトを作成するのではなく、建設この方法は、PandaオブジェクトとそのBambooアレイの両方を保持するために、単一のメモリブロックを割り当て:

class Panda 
{ 
    int a; 
    int b; 

    Panda() 
    { 
     // ... other initializations here ... 
    } 

    static Panda *createPanda (int count, Bamboo* bamboo) 
    { 
    byte* p = new byte[sizeof(Panda) + 
     sizeof(Bamboo) * count]; 
    new (p) Panda(); 

    Bamboo* bamboo = (Bamboo*) 
     p + sizeof(Panda); 

    // ... copy bamboo objects into the memory 
     // behind the object... 

     return (Panda*)p; 
    } 
} 

あなたは増加し、保守作業以外の第2の設計に問題を予見することはできますか?これは受け入れ可能な設計パターンですか、それとも後で私に噛み付くことができる時期尚早の最適化ですか?

+0

これは噛まれます。そして、それは辛いです。 –

+1

C++のクラス型のほとんどのセマンティクスを解消しています。可変長オブジェクトはC++では存在しません。 – jalf

+2

このようなハックに興味がある人は、Symbian/C++のTBuf8とTBuf16クラスのテンプレートをご覧ください。 –

答えて

9

C++には別のオプションがあります。 std :: vectorの使用を検討する必要があります。

class Panda 
{ 
    int a; 
    int b; 
    std::vector<Bamboo> bamboo; 
    // if you do not want to store by value: 
    //std::vector< shared_ptr<Bamboo> > bamboo; 

    Panda (int count, Bamboo* bamb) : bamboo(bamb, bamb+count) {} 
} 

あなたがthis articleからソリューションを使用することができ、連続メモリにパンダと竹を保存したい場合は

。主な考え方は、 operator newoperator deleteのオーバーロードです。

+0

このタイプのソリューションの副作用と対処しなければならない問題に注意する必要があります。ユーザーはコンテナ内のオブジェクトを使用できません(特にstd :: vectorはサイズに基づいてメモリを事前に割り当てます)。型が渡される)このトリッキーは、維持するのが難しいだけでなく(質問者が知っている)、使い方が不自然なコードでいっぱいになるでしょう –

+0

最も自然なのは 'std :: vector'です。他のすべてのソリューションは非常に限定されており、慎重に適用する必要があります。 –

+0

GCCの文字列実装はこの種のトリッキーを使います。そのトリックは、Pandaオブジェクトが(オーバーロードされた)実装クラスへの単一のポインタを含むかもしれないということです。 – UncleBens

1

"新しい"外観の新しい演算子を使用します。それは完全に正しい相対的なパンダですが、なぜBambooイニシャライザを使用しないのですか?

4

誰かが値段でパンダを取るなど、あなたは噛まれます。

//compiler allocates 16-bytes on the stack for this local variable 
Panda panda = *createPanda(15, bamboo); 

それは許容可能であるあなたはコピーコンストラクタと代入演算子を注意してください場合にのみ、これまでのポインタで、決して値で物事を参照してください、そして場合(ただし、非常におそらく時期尚早と恐ろしい最適化です)。

3

私の経験に基づいて、時期尚早の最適化は、ほとんどの場合、時期尚早です。つまり、コードをプロファイルし、最適化が必要かどうかを判断する必要があります。ロングラン。

また、最適化の価値についての質問は、BambooクラスのサイズとPandaごとのBambooオブジェクトの平均数に大きく依存しているようです。

3

これはCで見つかった。
しかし、C++では本当の必要はありません。

本当の質問は、なぜこれをやりたいのですか?

これは時期尚早の最適化です。内部的にstd :: vector <を使用すれば、問題はすべて消えます。クラスを使用すると、デフォルトのバージョンを上書きする必要が所有していることを

あなたが内部的にRAWのポインタを使用しているので:

  • デフォルトコンストラクタ
  • デストラクタ
  • コピーコンストラクタ
  • 代入演算子
  • 我々はそのプログラミングシンプルで人々を説得するにはどうすればよい
7

明快さ - 短く言えば、数学者が「エレガンス」と呼ぶものは、贅沢ではありませんが、成功と失敗を決める重要な問題です。

- エドガー・ダイクストラ

+0

ちょうどしないでください。多くのことが間違っている可能性があります...コピーコンストラクタ、代入、デストラクタをどのように実装しようとしていますか?あなたはパンダの配列を持ちたいユーザーにどのように対処しますか? –

+0

数学者はプログラミングと現実世界を知らない。 – Lothar

2

あなたはその絶望している場合は、おそらくこのような何か行うことができます。

template<std::size_t N> 
class Panda_with_bamboo : public Panda_without_bamboo 
{ 
    int a; 
    int b; 
    Bamboo bamboo[N]; 
} 

をしかし、私は、あなたが絶望的じゃないと信じていますが、途中で最適化します。

関連する問題