2012-06-11 11 views
12

Java'dan C++ 'ya bir bilimsel simülasyon platformu dönüştürdüm. Tasarımı, önceki uygulama ile olabildiğince aynı tutmaya çalıştım. Geç bağlama nedeniyle javada, döngüsel bağımlılıklar çalışma zamanında çözülür. Ancak, dairesel bağımlılıklar C++ 'da bir karışıklık yarattı.C++, karşılıklı ihtiyaçları olan iki sınıf

  1. Dairesel içerme ve referansları analiz eden ve listeleyen otomatik bir araç var mı? (Visual Studio 2010, sadece saçma sapan hataların büyük bir listesini verir).

  2. Mümkün olan yerlerde ileri referansları kullanmaya çalıştım. Bununla birlikte, bazı durumlarda her iki sınıfa da , diğer sınıfın işlevselliğine (yani, ileri referansın kullanılmasını imkansız kılan metotlara çağrı) ihtiyaç duyulmaktadır. Bu ihtiyaçlar Mantık'ta var olur ve eğer tasarımı kökten değiştirirsem gerçek dünya etkileşimlerini temsil etmeyeceklerdir.

    Birbirimizin yöntemlerine ve durumuna ihtiyaç duyan iki sınıfı nasıl uygularız? Onları C + + 'da uygulamak mümkün mü?

Örnekler:

  • Örnek 1: Ben tip "Ajan" nin Nesneleri yaratır "Dünya" adlı bir sınıf var. Ajan, çevreyi hakkında bilgi almak için Dünya yöntemlerini çağırmalıdır. Dünya'nın ayrıca Aracılar aracılığıyla yinelemesini ve "koşma" yöntemini çalıştırması ve durumlarını alması gerekir (durum güncellemeleri, sorunun bu bölümünü çözmek için tersine, ancak çalıştırma yöntemini tersine çevirmek zorunda kalabilir).
  • Örnek 2: Aracılar "Amaçları" nın bir koleksiyonunu oluşturur. Her Ajanın niyetleri doğrultusunda yinelemesi ve/update/read niyet durumunu çalıştırması gerekir. Niyetlerin ayrıca, Ajan aracılığı ile çevre hakkında bilgi almaları gerekmektedir (eğer doğrudan "Dünya" üzerinden yapılırsa, yine karmaşık çevreler yaratacaktır) ve ayrıca Ajanın kendisinin bilgisi. diyagram Aşağıda

sınıfların bir alt kümesini gösterir ve onların yöntemleri ve bazı özelliklerini:

sub-set of classes, and some of their methods and properties

+0

Hatalarla ilgili sorun yaşarsanız, bu hataları içeren bir soruyu her zaman gönderebilirsiniz (sözdizim lütfen) ve birileri size büyük olasılıkla yardımcı olabilir. Ayrıca, bu hatalar size saçma olabilir, ama başkasına değil. Bazı kodları görmeden soruları cevaplamak çok zordur ve bunun için http://sscce.org/ adresini okumanızı tavsiye ederim. –

+0

Joachim, Dairesel bağımlılık durumlarında oluşan hataların türüdür. Sınıflar belirlenemez. 'code' 1> e: \ programming \ cprojt \ actiondb11 \ actiondb \ base \ world.h (35): hata C2143: sözdizimi hatası: eksik ',' önce '*' 1> e: \ programming \ cprojt \ actiondb11 \ actiondb \ base \ world.h (36): hata C2061: sözdizimi hatası: tanımlayıcı 'Ajan' 1> e: \ programming \ cprojt \ actiondb11 \ actiondb \ base \ world.h (50): error C2065: ' Agent ': bildirilmemiş tanımlayıcı – wmac

+1

Kodun gönderilmesi, hataların kaydedilmesinden çok daha yararlıdır. Gönderme * her ikisi de en iyisidir. –

cevap

17

Bildirim bildirimlerinin sizin için işe yaramadığını göremiyorum.

World.h:

#ifndef World_h 
#define World_h 

class Agent; 

class World 
{ 
    World(); 
    void AddAgent(Agent* agent) { agents.push_back(agent); } 
    void RunAgents(); 
private: 
    std::vector<Agent*> agents; 
}; 

#endif 

Agent.h:

#ifndef Agent_h 
#define Agent_h 

class World; 
class Intention; 

class Agent 
{ 
    Agent(World& world_): world(world_) { world.AddAgent(this); } 
    status_t Run(); 
private: 
    World& world; 
    std::vector<Intention*> intentions; 
}; 

#endif 

World.cc:

#include "World.h" 
#include "Agent.h" 

void World::RunAgents() 
{ 
    for(std::vector<Agent*>::iterator i = agents.begin(); i != agents.end; ++i) 
    { 
     Agent& agent(**i); 
     status_t stat = agent.Run(); 
     // do something with stat. 
    } 
} 

// ... 

Ajan Bu gibi bir şey gerekiyor gibi görünüyor.cc:

#include "Agent.h" 
#include "World.h" 
#include "Intention.h" 

// ... 
+1

Cpp dosyalarının en üstünde bulunan dosyalar dahil olmak üzere referansları tekrar deneyeceğim. Umarım bu problemleri çözerdi. – wmac

+3

Dil tarafından istenmese de, kodun tamamını okuyan birinin bağımlılıkları hızlı bir şekilde bilmesi için, tüm içeriklerini dosyanın başında koymak iyi bir uygulamadır. –

+1

Sadece referansları değil, B tipi A tipi gerçek örnekleri ve tam tersi bir çözüm var mı? Derleyiciden "eksik tip" hatası alıyorum, bu da mantıklı. Ama etrafında herhangi bir yolu var mı? –

3

Sen sadece ileri beyanları ile sorunu çözebilir, ancak muhtemelen değil mi' Uygulamayı sınıfın beyanından ayırmak.

Sınıftan yöntem çağırmanız gerekirse, tam bir tür gerekir; bu nedenle dosyayı eklemeniz gerekir. Dairesel bağımlılıklar hakkında endişelenmeden dosyayı cpp (uygulama dosyası) içine ekleyebilirsiniz.

+0

Teşekkürler Luchian. Uygulamam ayrı, ancak ileriye dönük başvurularla birlikte cpp dosyalarına taşıma işlemini gerçekleştirmedim. – wmac