0

所以這裏是交易,我認爲我需要去關於我使用的模式的另一條路線,但我想我會首先得到一些專家意見。多態性與=操作符使用指針基類

我有一個類(UsingClass),它維護基類指針的動態列表。當向列表中添加一個新對象時,我必須弄清楚它是什麼類型的對象,因爲我無法真正以多態的方式使它工作。下面一行標記爲「這不會像我想要的那樣工作!」理想情況下多態地使用來自Derived類的=運算符,但不幸的是它只使用Base類的default =運算符......如果我將Base純虛擬化(基本上將它用於沒有接口的接口它自己的數據成員),但我並不想讓派生類擁有兩者之間常見的成員(也許我需要切割誘餌並執行它)。

我想我可能只是完全使用了錯誤的模式,但我不知道我應該考慮替代方案。

我知道代碼不一定編譯,但請與我一起工作。提前致謝!

//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 
}; 
+2

你的問題不清楚。也許你應該首先告訴我們你實際上想要實現什麼,而不是試圖解決你的解決方案... –

+1

在我看來你想要一個'clone()'方法... google clone,你應該找到大量的例子。 –

+0

http://icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html這可以清理很多事情。 – DumbCoder

回答

3

而不是檢查類型,你可以簡單地添加一個虛擬函數的類'基',並調用它。這將簡化無效functionAddDerivedToList(*基礎myInputPtr)以下:

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

克隆總是被實施,以調用類的拷貝構造函數。因此,在基地,添加以下內容:

virtual Base* clone() = 0; 

的實施將始終採取這種形式(例如是Derived1,基地在你的例子子類):

virtual Base* clone() { return new Derived1(*this); } 
0

一個問題,我看到的是,您將唱C風格的數組以包含「基本」對象的列表。請注意,在這種情況下,數組中元素的大小將是sizof(Base),它與sizeof(Derived1)和sizeof(Derived2)不同。這兩個派生也可能不同。在這種情況下你可以做的是讓數組包含Base對象的指針而不是實際的對象。這將使大小統一爲4個字節,並且您可以訪問陣列中的對象作爲指針。因爲數組現在包含指針,所以如果只是想將它們插入到數組中,則不必確定類型。

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

如果你想訪問數組中的對象,你可以做這樣的事情。

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

您可以相信,在這種情況下,將根據實際的p類型調用正確的MyMethod函數。

0

我有一個類(UsingClass),它維護基類指針的動態列表。

很抱歉,但你沒有(錯誤的語法)。但不要這樣。

首先,給你的Base類虛析構函數。否則,你會遇到內存泄漏。

然後,重新設計UsingClass容器。給它一個shared_pointer矢量給Base成員以保存動態分配的多態對象。 (如果你使用非的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您可以容納多個指向一個對象的指針,而不必關心釋放內存。複製指針不會複製對象(所謂的淺拷貝)。如果您確實需要複製對象(所謂的深度複製),則您的Base和派生類將不得不實施虛擬clone()方法。