2012-11-10 13 views
2

可能重複對象的虛函數:
Overriding parent class’s function如何調用C++

我與調用在C虛函數++掙扎。我沒有C++經驗,我主要使用C#和Java,所以我可能會有一些妄想,但忍受着我。

我必須編寫一個程序,我必須儘可能避免動態內存分配。我創建了一個名爲List的類:

template <class T> class List { 
public: 
    T items[maxListLength]; 
    int length; 


    List() { 
     length = 0; 
    } 

    T get(int i) const { 
     if (i >= 0 && i < length) { 
      return items[i]; 
     } else { 
      throw "Out of range!"; 
     } 
    }; 

    // set the value of an already existing element 
    void set(int i, T p) { 
     if (i >= 0 && i < length) { 
      items[i] = p; 
     } else { 
      throw "Out of range!"; 
     } 
    } 

    // returns the index of the element 
    int add(T p) { 
     if (length >= maxListLength) { 
      throw "Too many points!"; 
     } 
     items[length] = p; 
     return length++; 
    } 

    // removes and returns the last element; 
    T pop() { 
     if (length > 0) { 
      return items[--length]; 
     } else { 
      throw "There is no element to remove!"; 
     } 
    } 
}; 

它只是生成一個給定類型的數組,並管理它的長度。

無需動態內存分配,我可以只寫:

List<Object> objects; 
MyObject obj; 
objects.add(obj); 

MyObject來繼承表單對象。對象有哪些是應該在爲MyObject被覆蓋的虛函數:

struct Object { 
    virtual float method(const Input& input) { 
     return 0.0f; 
    } 
}; 

struct MyObject: public Object { 
    virtual float method(const Input& input) { 
     return 1.0f; 
    } 
}; 

我得到的元素:

objects.get(0).method(asdf); 

的問題是,即使第一個元素是myObject的,對象的方法函數被調用。我猜測存儲對象的數組中沒有爲MyObject動態分配內存有問題,但我不確定。

有沒有辦法調用MyObject的方法函數?怎麼樣?它應該是一個異構集合順便說一句,所以這就是爲什麼繼承是在那裏擺在首位。

如果沒有辦法調用MyObject的方法函數,那麼我應該如何在第一個地方創建我的列表?

此外,我無法訪問math.h和stdlib.h之外的庫,因此無法使用vector。

+3

對象切片總是很有趣。你需要一個指針列表。 – chris

+0

http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c什麼切片是 – Mat

回答

1

當你這樣做:

objects.add(obj); 

要添加爲MyObject到列表中的對象部分的副本,因此它不再是爲MyObject。

你也許會嘗試這樣做:

int add(T const &p) { 
    if (length >= maxListLength) { 
     throw "Too many points!"; 
    } 
    items[length] = p; // now the problem is here 
    return length++; 
} 

但現在p的對象部分的副本任務中發生的。

爲了讓列表成爲異類,它必須是一個指針列表,但是你也想避免動態內存分配。您可以避免動態內存分配,如果你很小心:

Object obj1; 
MyObject obj2; 
List<Object*> object_ptrs; 
object_ptrs.add(&obj1); 
object_ptrs.add(&obj2); 
 object_ptr.get(1)->method(input); 
object_ptr.get(0)->method(input); 

但同樣,你必須要非常小心。該列表現在指向堆棧上的兩個對象。如果你從這個函數返回,這兩個對象將被銷燬。請注意,我有意將對象指針列表放在對象之後,以便列表在對象之前被銷燬,所以列表不會被指向垃圾。但是,如果您返回列表的副本,則仍然存在問題。

+0

如果add函數具有參數add(T&p)會怎麼樣? – SoonDead

+1

@SoonDead:這隻會推遲問題,直到分配。當你說'items [length] = p'時,你只需要複製p的Object部分。 –

+0

函數簽名是好的,但是當它被添加到列表中時它會被切片... – Caribou

4

您需要將指針存儲在列表中。試試這個:

List<Object*> objects; 
Object *obj1 = new Object; 
MyObject *obj2 = new MyObject; 
Object *obj3 = new MyObject; 

objects.add(obj1); 
objects.add(obj2); 
objects.add(obj3); 

// This calls the implementation in Object class 
objects.get(0)->method(asdf); 

// This calls the implementation in MyObject class 
objects.get(1)->method(asdf); 

// This calls the implementation in MyObject class 
// Polymorphism here 
objects.get(2)->method(asdf); 

希望這會有所幫助。

+0

我最終接受了另一個答案,因爲這裏有一個很好的解釋,但這個答案也有幫助。 – SoonDead

+0

很高興你知道了。 –