2009-06-05 12 views
22

Belirli bir sınıfın satır içi üye işlevlerini kullanmaya çalışıyorum. Ben "koyarsanızsatır içi işlev bağlayıcı hatası

int NeedleUSsim::GetTplLSize() 
{ 
    return sampleDim[1]; 
} 

Nedense:

int GetTplLSize(); 

.Cpp dosyasında: başlık dosyasına

: gibi Örneğin inlining olmadan fonksiyon beyanı ve uygulamasıdır inline "anahtar kelimesi, uygulama ve bildirimin yanı sıra, her iki yerde de gösterildiği gibi, bağlayıcı hataları alırım:

 
Creating library C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.x and object C:\DOCUME~1\STANLEY\LOCALS~1\TEMP\MEX_HN~1\templib.exp 
mexfunction.obj : error LNK2019: unresolved external symbol "public: int __thiscall NeedleUSsim::GetTplLSize(void)" ([email protected]@@QAEHXZ) referenced in function _mexFunction 
mexfunction.mexw32 : fatal error LNK1120: 1 unresolved externals 

    C:\PROGRA~1\MATLAB\R2008B\BIN\MEX.PL: Error: Link of 'mexfunction.mexw32' failed. 

Bu hatadan kurtulmak için ne olması gerekir (ör. Bu satır içi üye işlevleri yapmak açısından ne yapıyorum?)?

cevap

23

İşlev tanımını daha sonra üstbilgiye yerleştirmeniz gerekir.


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const; 
    // ... 
}; 

inline int NeedleUSsim::GetTplLSize() const 
{ return sampleDim[1]; } 

tanım olmalı: Eğer ayrı beyanı ve tanımı ısrar,


class NeedleUSsim 
{ 
    // ... 
    int GetTplLSize() const { return sampleDim[1]; } 
    // ... 
}; 

ya: satır içi derleyicisi ipucu en basit yolu gibi sınıf bildiriminde yöntem gövdesine dahil etmektir Her çeviri biriminde bu yöntemi kullanan görünür.

C++ SSS Lite'dan
+0

Tek yol bu mu? (Ben okunabilirlik nedenleriyle bildirimi ve uygulamayı ayrı ayrı ayırmak istiyorum) – stanigator

+1

Temel olarak evet. Derleyici, çağrılar derlenirken, fonksiyonun gövdesini bilmek zorundadır, bu yüzden gövde, dahil edilen başlık dosyasında olmalıdır. Bununla birlikte, yine de, yalnızca sınıf beyanındaki işlevi bildirebilir ve uygulamayı, başlık dosyasında daha sonraki bir yere ekleyebilirsiniz. – Hans

+0

Anladım. Sanırım kodu bu şekilde yazarak yaşamak zorundayım. Tavsiyeler için teşekkürler. – stanigator

2

Satır içi bir işleviniz varsa, tanımı üstbilgi dosyasına koymalısınız.

+0

Satır içi anahtar kelimeyi başlık dosyasındaki tanımlara koymaya çalıştım ve hala aynı bağlayıcı hatasıyla karşılaşıyorum. – stanigator

+2

Sadece satır içi anahtar kelime değil, tüm tanım başlık dosyasında gitmelidir. Yani, .cpp dosyasından .h dosyanıza taşıyın. – ChrisInEdmonton

+1

Tanım, beyan değil. –

17

bir .cpp dosyasına satır içi işlevin tanımını koymak ve bu diğer bazı .Cpp dosyasından aranırsa bir "çözülmemiş dış döneriz " bağlantıdan hata. Diğerleri zaten işaret gibi

How do you tell the compiler to make a member function inline?

+0

işe yaramazsa, zor yoldan öğrendiğim gibi, bu MSVC 2013 ve 2015'te durum böyle değil. bir CPP dosyasında (bir kütüphanede) satır içi ve onun kodu, aynı ada sahip bir satır içi (ama biraz farklı bir kod olan bazı tamamen farklı CPP kaynak kodundan) çağrıldı, böylece sonuç testleri bozdu. Bu geliştirme ortamında bir hata olduğunu düşünüyorum. Bulması zor... – chksr

3

, bunu gibi başlık dosyasına satır içi fonksiyonun tanımını taşımak gerekir:

class NeedleUSsim 
{ 
    // ... 
    inline int GetTplLSize() { return sampleDim[1]; } 
    // ... 
}; 

Bunun nedeni olduğunu Derleyici, satır içi işleve bir çağrı gördüğünde satır içi kodun ne olduğunu bilmelidir. Işlev tanımını, NeedleUSsim sınıfının .cpp dosyasında bırakırsanız, derleyicinin kendisi için ürettiği kod, NeedleUSsim nesne dosyasında yakalanır. Derleyici sadece kaynak kodu —'u okurken, başka bir sınıfın — nesne dosyasına hiçbir zaman göz atmaz, başka bir .cpp dosyası derlerken bir aramanın hangi kodla değiştirileceğini bilmenin bir yolu yoktur.

0

Bkz. Inline Guard Macro idiom. Bu, en azından bildirgeden gelen kodu biraz da olsa ayırmanıza izin verecektir. Ayrıca, define aracılığıyla işlevlerin satırlarını değiştirmenizi sağlar.