2011-03-05 30 views
6

Kısa Açıklama:
Bir dizi eylemi yürütmek için vektördeki her nesnede sanal bir işlev çağırmak üzere bir vektör üzerinde yinelemiyorum. Vektör, yineleyici olduğu gibi temel sınıftadır. Bütün nesneler çocuklar. Sanal işlev çağrıldığında, temel sınıfın işlevini yürütür.Sanal İşlevler: Alt sınıf nesneleriyle doldurulmuş <Base Class> numaralı vektörün üzerinde yineleme

(Gerçekten) Uzun Açıklama: Bir dizi davranışı olan bir yaratığı modellemeye çalışıyorum. Benim taban sınıfı bütün alt sınıflar geçersiz kıldık sadece iki fonksiyonları (sanal) ile soyut:

class Behavior 
{ 
public: 
    Behavior(); 
    ~Behavior(void){} 
virtual void execute(){} 
virtual BEHAVIOR_TYPE getType() {return m_Type;} 


protected: 
BEHAVIOR_TYPE m_Type; 
}; 

Böyle bir hareket olarak çocukların davranışları, bir dizi oluşturduk, vb, iş takipçisi tüketmek

class Move : 
    public Behavior 
{ 
public: 
BEHAVIOR_TYPE getType() {return m_Type;} 
    enum Direction {N, NE, E, SE, S, SW, W, NW}; 
Move(DOCO * d); 
~Move(void); 
void execute() ; 
    Direction chooseDirection(); 
    void setDirection(Direction newDirection); 
private: 
    Direction m_Direction; 
    DOCO *I; 
BEHAVIOR_TYPE m_Type; 

}; 

yaratık bir eylem dizisini alır
vector<Behavior> m_Behavior; 
vector<Behavior>::iterator bIt; 

ben iterat deneyin:

I her Davranış alt sınıfının örnekleri itilir, bunun üzerine bir vektör ve hem de daha çapraz bir yineleyici oluşturulan vektör üzerinden e, yineleyici KQUEUE ve çağrı yürütmek fonksiyonu:

void World::justDoIt() 
{ 
    for(dIt=myDOCO.begin(); dIt!=myDOCO.end(); ++dIt) 
{ 
    vector<Behavior>::iterator myBehavior=(dIt)->getFirstBehavior(); 
    vector<Behavior>::iterator end=(dIt)->getLastBehavior(); 
    for(myBehavior; myBehavior!=end; ++myBehavior) 

     (*myBehavior).execute(); 
} 
} 

sorun çocuğun işlevi yerine ebeveynin işlevini yürütür olmasıdır.

Geç bağlama konusundaki anlayışımda, çağrılan işaretçi türünden ziyade, onu çağıran nesnenin türüne göre uygun işlevi otomatik olarak çağırmalı ve kodumda bunu işaret ettiğimi tahmin ediyorum. çocuk nesnesi.

Açıkçası, bir hata yaptım ve bir şekilde programın çocuk yerine ebeveynler gibi davranılmasını istediğimi söyledim, ama hatayı bulamıyorum. İkinci bir semptom, ebeveynleri saf sanallaştırma işlevini yerine getirmeme izin vermeyeceğidir, çünkü soyut bir sınıfı başlatamayacağını söylemektedir. Kodumda açıkça herhangi bir yerde onu oluşturmuyorum, ancak bunu bir yerde yapmak zorundayım. Ancak nerede olduğunu bulamıyorum. Kesinlikle, üst sınıfın nesnelerini tutacak bir vektör oluşturmak, üst öğeyi örneklemeyi gerektirmez ve bu, üst sınıfı doğrudan başvurduğum tek zamandır.

Herhangi bir yardım büyük memnuniyetle karşılanacaktır.

+0

Orada bir içine (ziyade _pointers_ yerine) taban sınıfı _objects_ koymak için safdilli onlarca olmalı STL konteynırı, yapamam, ATM, birini bul. Bunlardan biri muhtemelen [SSS girişi] olmalıdır (http://stackoverflow.com/questions/tagged/c%2b%2b-faq). – sbi

cevap

10

vector<Behavior> sınıfı, kopya oluşturucu Behavior::Behavior(const Behavior&);'u kullanarak içinde sakladığınız her nüshasının bir kopyasını oluşturur. Bu polimorfizmi yok eder. Bunun yerine kap içinde bir işaretçi veya akıllı işaretçi kullanmak gerekir:

vector<Behavior*> m_Behavior; // I will take care of new and delete 
vector<shared_ptr<Behavior> > m_Behavior; // easier 

Eğer #include <memory> veya benzeri içinde std::shared_ptr veya std::tr1::shared_ptr yoksa, belki Boost en kullanabilirsiniz.

+0

Çok teşekkür ederim! Paylaşılan işaretçiler hakkında bilmiyordum! Eğer std :: shared_ptr' varsa – Sisyphus

+2

, 'std :: unique_ptr' komutunu kullanın. –

4

Vektörlere örneğini sınıfları eklemektesiniz. Bu, slicing ile sonuçlanır.Yapmanız gereken şey

davranışların örneklerine işaretçiler ekleyin ve yapılacak döngü değiştirmek olduğunu

(*myBehavior)->execute(); 
+0

Çok teşekkür ederim! – Sisyphus

İlgili konular