2011-01-13 28 views
8

Söz konusu sınıflar *.h ve *.cpp files olarak ayrıldığında, bazı soyut sınıflardan miras alınan saf sanal işlevleri uygulamada bazı sorunlar yaşıyorum. Derleyici (g++), türetilmiş sınıfın, salt işlevlerin varlığı nedeniyle başlatılamayacağını söyler. Arayüz en *.h ve çok derived.h yılında - C++ 'nin salt sanal işlev uygulaması ve başlık dosyaları

/** interface.h**/ 
namespace ns 
{ 
    class Interface { 
     public: 
      virtual void method()=0; 
    } 
} 

/** interface.cpp**/ 
namespace ns 
{ 
    //Interface::method()() //not implemented here 
} 

/** derived.h **/ 
namespace ns 
{ 
    class Derived : public Interface { 
     //note - see below 
    } 
} 

/** derived.cpp **/ 
namespace ns 
{ 
    void Derived::Interface::method() { /*doSomething*/ } 
} 

/** main.cpp **/ 
using namespace ns; 
int main() 
{ 
    Interface* instance = new Derived; //compiler error 
} 

bu iki kez) ( yöntem bildirmek gerektiği anlamına mı geliyor? Etrafta başka yolu yok mu?

+0

Bu geçerli değil C++. public void method() = 0; 'bana daha çok Java gibi görünüyor. –

+0

İlk olarak, tek şeyin boş bir ad alanı olduğu bir .cpp dosyasının olması için bir neden yoktur. Bir soyut dersi kabul eden bir başlık için bir uygulama dosyasına ihtiyacınız yoktur. – Falmarri

+0

@Falmarri doğrudur. –

cevap

12

Derived::method() bildirmeyi unuttunuz.

En azından bunu tanımlamak için çalıştı, ama Derived::method() yerine Derived::Interface::method() yazdı, ama sen bile beyan girişimi yoktu. Bu nedenle mevcut değil.

Dolayısıyla Derived nedenle saf sanal işlevi method()Interface dan geçersiz değildi ... ve bu nedenle, Derived da sanal saf ve başlatılamaz, hiçbir method() sahiptir. Ayrıca, public void method()=0;, C++; Java'ya daha çok benziyor. Saf sanal üye işlevleri aslında sanal olmalı, ancak virtual yazmadınız. Ve erişim belirleyicileri aşağıdaki gibi iki nokta üst üste izler:

+0

Boşluk muhtemelen bir yazım hatası, bu da java değil. – time4tea

+0

@ time4tea: Gerçekten de geçerli bir Java değil, eksik kolon ve erişim belirtecinin deklarasyonla birleştirilen bir şey olarak görülmesiyle, C++ için olduğundan daha yakın bir görüntüdür! –

+0

Sözdizimi yazım hatasıydı, açılış yayına yaptığım yorumu görün :) bunun için üzgünüm. Ayrıca, "Türetilmiş :: Arabirim :: yöntemi()", Arabirim'den miras alınması gereken bir işlevi tanımlama girişimimdir. Orijinal sorum, satırlar boyunca bir şeydi, "türetilmiş bir sınıfın' .h 'dosyasında açıkça bildirilmeden devralınan bir saf sanal işlevi uygulayabilirim (tanımlayabilir miyim? "). Bunu yapmak istediğim şey, sınıf başlığı birkaç arabirimden miras aldığında, başlık dosyamın dağılmasını engellemektir ... – Neo

11

Yönteminizi alt sınıfta beyan etmeniz gerekir.

// interface.hpp 
class Interface { 
public: 
    virtual void method()=0; 
} 

// derived.hpp 
class Derived : public Interface { 
public: 
    void method(); 
} 

// derived.cpp 
void 
Derived::method() 
{ 
    // do something 
} 
+0

Sanırım ** declare ** (tanımlamıyor). –

+0

@MikeSlutsky evet yaptım. – robert

+0

@robert Cevabınız için teşekkür ederiz. Bunun nedenlerini açıklayabilir misiniz? Java'dan gelmek zorunda olmak çok kirli görünüyor. Baz arayüzde birçok farklı sınıf ve birçok yöntem bulunduğumuzda, temel arayüzde değişiklik olması durumunda birçok dosyayı değiştirmemiz gerekir. –

İlgili konular