2016-04-08 36 views
3

Yalnızca bir başlık kitaplığı uygulamasını aşağıdaki gibi düşünün: foo ve çubuk döngüsel bağımlılığa sahip. Bir (client.cpp) dosyasında bu başlığı içeren ve dışarı yorum girmeTek bir başlıktaki kitaplıktaki döngüsel bağımlılık

class bar; 
class foo { 
public: 
    foo(std::shared_ptr<bar> bar_){ 
     //bar_->mar() 
    } 
    void moo() {}; 
}; 


class bar { 
    bar(std::shared_ptr<foo> foo_) { 
     foo_->moo(); 
    } 
    void mar() { }; 
}; 

// çubuğu _-> mar(), derleyici hata veriyor:

error C2027: use of undefined type 'bar' 
see declaration of 'bar' 
error C2039: 'mar': is not a member of 'std::shared_ptr<bar>' 

çözülebilir verilen sorundur kütüphanenin sadece başlık olduğunu mu?

cevap

2

Sorun, sınıf tanımından önce "bar" sınıfının "marr()" yöntemini çağırmaya çalıştığınız için oluşur. "Bar _-> mar();" dediğinizde yalnızca "bar" sınıfı belirttiniz. derleyici bir sınıf "bar" olduğunu bilir ama hangi yöntemlerin olduğunu bilmez. Çözüm, "bar" tanımından sonra "foo" kurucusunu çağırmaktır. Kitaplığınız yalnızca üstbilgi ise "satır içi" olarak bildirebilirsiniz. ...

#pragma once 
#include <memory> 

class bar; 
class foo { 
public: 
    foo(std::shared_ptr<bar> bar_); 
    void moo() {}; 
}; 


class bar { 
public: 
    bar(std::shared_ptr<foo> foo_) { 
     foo_->moo(); 
    } 
    void mar() { }; 
}; 

inline foo::foo(std::shared_ptr<bar> bar_){ 
    bar_->mar(); 
} 
-1

Sınıflarınızı .h ve .cpp dosyalarına bölmeniz daha iyi olur. Onları aynı zamanda .h ve .hh bildirimi ve uygulamasıyla her iki başlığa da bölebilirsiniz, ancak bunları iki veya daha fazla farklı çeviri biriminde kullanarak bağlamaya çalışırken sorunlarınız olacaktır. Bir hack olarak, sınıflarınızı bazı parametrelerle şablonlara dönüştürebilir ve bunları her ikisinde de rastgele tipte ama aynı zamanda uzmanlaşmak için kullanabilirsiniz, ancak bu, iyi bir sulution imho değildir. Şablon kesmek:

foo.h

#ifndef FOO_H 
#define FOO_H 

#include "foo.h" 

template <typename T> class bar; 


template <typename T> 
class foo 
{ 
public: 
    foo(std::shared_ptr<bar<T> > bar_); 
    void moo(); 
}; 

#endif // FOO_H 

foo.hh

#ifndef FOO_HH 
#define FOO_HH 

#include "foo.h" 

#include "bar.h" 


template <typename T> 
foo<T>::foo(std::shared_ptr<bar<T> > bar_) 
{ 
    bar_->mar(); 
} 


template <typename T> 
void foo<T>::moo() 
{ 
} 

#endif // FOO_HH 

bar.h

#ifndef BAR_H 
#define BAR_H 

#include <memory> 

template <typename T> class foo; 

template <typename T> 
class bar 
{ 
public: 
    bar(std::shared_ptr<foo<T> > foo_); 
    void mar(); 
}; 

#endif // BAR_H 

bar.hh

#ifndef BAR_HH 
#define BAR_HH 

#include "bar.h" 

#include "foo.h" 

template <typename T> 
bar<T>::bar(std::shared_ptr<foo<T> > foo_) 
{ 
    foo_->moo(); 
} 

template <typename T> 
void bar<T>::mar() 
{ 
}; 

#endif // BAR_HH 
+2

"Bu başlık okunur olmayan kütüphane Uygulamayla ilgili sınıfları var çünkü." Ben yazar başlıklardaki uygulama vardır anlayabileceği gibi bu nedenle bununla bu yüzden sence:

Bu kod Tamam derler başlık sadece kütüphane değil mi? – Sandro

+1

Bir başlık sadece kütüphane uygulama ile IS sınıfları. – goldcode

İlgili konular