0

これが契約です。使用しているパターンに関して別のルートに進む必要があると思いますが、最初に専門家の意見を得ると思いました.

基本クラス ポインターの動的リストを保持するクラス (UsingClass) があります。リストに新しいオブジェクトを追加するときは、それがどのタイプのオブジェクトであるかを把握する必要があります。これは、ポリモーフィックな方法で実際に機能させることができないためです。以下の行には、「これは私が望むようには機能しません!!」というタグが付けられています。興味のある Derived クラスから =operator をポリモーフィックに使用するのが理想的ですが、残念ながら Base クラスのデフォルトの =operator しか使用しません。独自のデータメンバー)、しかし、派生クラスに両方に共通のメンバーを保持させたくありません (おそらく、餌を切ってそれを行う必要があるかもしれません)。

完全に間違ったパターンを使用している可能性があると思いますが、どの代替案を検討すべきかわかりません。

コードが必ずしもコンパイルされるとは限りませんが、私と一緒に作業してください。前もって感謝します!

    //code block
class Base { 
  protected: 
    int x;   
    float y;  
    string type;   // default to Derived1 or Dervied2 depending on the object inst  

  public:
    virtual int functionM(int l) = 0; 
    int functionN(int P);  
};  

class Derived1 : public Base { 
  protected:  
    int a;  

  public:  
   int functionM(int l); 
   float functionR(int h);  
};  

class Derived2 : public Base {  
  protected: 
     int b;  
     float r;  

  public: 
    int functionM(int l); 
    float functionR(int h); 
}; 

#define MAX_ARRAYSIZE   10 

class UsingClass { 
  private: 
    Base* myDerived1And2DynamicList[MAX_ARRAYSIZE];
    int indexForDynamicList;   

  public: 
    void functionAddDerivedToList(*Base myInputPtr) {  
       if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {  
           if(myInputPtr->type == "Derived1") {  
                myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived1;  
                *myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!  
            } else if (myInputPtr->type == "Derived2") { 
                myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived2;  
                *myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!  
            } 
        }  
     } // end of void function 
};
4

3 に答える 3

3

タイプをチェックするのではなく、仮想関数をクラス「Base」に追加して呼び出すことができます。これにより、void functionAddDerivedToList(* Base myInputPtr)が次のように簡略化されます。

void functionAddDerivedToList(*Base myInputPtr)
{
   if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {  
       myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr->clone();
   }
}

クローンは、クラスのコピーコンストラクターを呼び出すために常に実装されます。したがって、Baseに次を追加します。

virtual Base* clone() = 0;

実装は常にこの形式を取ります(例はDerived1の場合で、この例ではBaseのサブクラスです)。

virtual Base* clone() { return new Derived1(*this); }
于 2011-07-22T04:03:02.033 に答える
0

私が見る 1 つの問題は、「ベース」オブジェクトのリストを含めるために C スタイルの配列を歌っていることです。この場合の配列内の要素のサイズは、sizeof(Derived1) および sizeof(Derived2) とは異なる sizof(Base) になることに注意してください。両方の派生物も異なる場合があります。この場合にできることは、配列に実際のオブジェクトの代わりに Base オブジェクトのポインターを含めることです。これにより、サイズが 4 バイトに統一され、配列内のオブジェクトにポインターとしてアクセスできるようになります。配列にはポインターが含まれるようになったため、単純に配列にポインターを挿入する場合は、型を判別する必要はありません。

void functionAddDerivedToList(Base* myInputPtr)
{
    if((indexForDyanmicList + 1) < MAX_ARRAYSIZE)
        myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr;
}

配列からオブジェクトにアクセスしたい場合は、次のようにすることができます。

Base* p = myDerived1And2DynamicList[index];
p->MyMethod();

この場合、 p の実際の型に基づいて正しい MyMethod 関数が呼び出されることを信頼できます。

于 2011-07-22T04:48:21.637 に答える
0

基本クラス ポインターの動的リストを保持するクラス (UsingClass) があります。

申し訳ありませんが、そうではありません (間違った構文)。しかし、そのように行かないでください。

まず、Baseクラスに仮想デストラクタを与えます。そうしないと、メモリ リークが発生します。

次に、UsingClassコンテナーを再設計します。動的に割り当てられたポリモーフィック オブジェクトを保持する Base メンバーへの shared_pointer のベクトルを指定します。(C++0x 以外のコンパイラを使用する場合は、 を使用できますstd::tr1::shared_ptr。)

class UsingClass { 
private: 
  std::vector<std::shared_ptr<Base> myList;
  // int indexForDynamicList; is now myList.size()  

public: 
  void Add(Base* myInputPtr) {  
    myList.push_back(myInputptr);
  }
// ...
};

ポリモーフィック オブジェクトを追加するには、次を使用します。

UsingClass container;
container.add(new Base);
container.add(new Derived1);
container.add(new Derived2);

反復することで、すべてのポリモーフィック メソッドを呼び出すことができます

for (size_t i = 0; i < myList.size(); ++i)
{
  myList->functionM();  // give the function a more "speaking" name
} 

を使用shared_ptrすると、1 つのオブジェクトへの多くのポインターを保持でき、メモリの解放を気にする必要がなくなります。ポインターをコピーしても、オブジェクトはコピーされません (浅いコピーと呼ばれます)。オブジェクトもコピーする必要がある場合 (いわゆるディープ コピー)、作成Baseしたクラスと派生クラスで仮想clone()メソッドを実装する必要があります。

于 2011-07-22T07:28:28.367 に答える