ISO C ++ Standardı, saf sanal olmayan bir sınıfın tüm sanal yöntemlerinin tanımlanması gerektiğini belirtir.
Basitçe şu kuralı koyun:
Türetilmiş sınıfınız Base sınıfı sanal yöntemini geçersiz kılıyorsa, o zaman bir tanım da sağlamalıdır, değilse, o zaman Base sınıfı bu yöntemin tanımını sağlamalıdır.
Kod örneğinizdeki yukarıdaki kurala göre virtual void bar();
, Base sınıfında bir tanıma ihtiyaç vardır.
Referans:
C ++ 03 Standart: 10.3 Sanal işlevler [class.virtual]
Bir sınıfta beyan edilen sanal bir işlev, o sınıfta veya her ikisinde de tanımlanmalı veya saf ilan edilmelidir (10.4); ancak teşhis gerekmez (3.2).
Yani ya işlevi tamamen sanal yapmalı ya da onun için bir tanım sağlamalısınız.
Gcc sss doccuments yanı o:
ISO C ++ Standardı, saf sanal olmayan bir sınıfın tüm sanal yöntemlerinin tanımlanması gerektiğini belirtir, ancak bu kuralın ihlalleri için herhangi bir tanı gerektirmez [class.virtual]/8
. Bu varsayıma dayanarak, GCC yalnızca örtük olarak tanımlanmış kurucuları, atama işlecini, yıkıcıyı ve bu tür ilk satır içi olmayan yöntemi tanımlayan çeviri birimindeki bir sınıfın sanal tablosunu yayınlayacaktır.
Bu nedenle, bu belirli yöntemi tanımlayamazsanız, bağlayıcı, görünüşte ilgisiz semboller için tanımların eksikliğinden şikayet edebilir. Ne yazık ki, bu hata mesajını iyileştirmek için bağlayıcıyı değiştirmek gerekebilir ve bu her zaman yapılamaz.
Çözüm, saf olmayan tüm sanal yöntemlerin tanımlanmasını sağlamaktır. Bir yıkıcının, saf sanal olarak bildirilmiş olsa bile tanımlanması gerektiğini unutmayın [class.dtor]/7
.