Anladığım kadarıyla override
, C ++ 11'de anahtar kelimenin tanıtımı, uygulanan işlevin temel sınıfta override
bir virtual
işlev olduğundan emin olmak için bir denetimden başka bir şey değildir .
Öyle mi?
Anladığım kadarıyla override
, C ++ 11'de anahtar kelimenin tanıtımı, uygulanan işlevin temel sınıfta override
bir virtual
işlev olduğundan emin olmak için bir denetimden başka bir şey değildir .
Öyle mi?
Yanıtlar:
Aslında fikir budur. Mesele şu ki, ne demek istediğiniz konusunda açık olursunuz, böylece sessiz bir hata teşhis edilebilir:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Yukarıdaki kod derlenir, ancak ne demek istediğiniz değil (eksik olduğuna dikkat edin const
). Bunun yerine, virtual int foo() override
dediyseniz, işlevinizin aslında hiçbir şeyi geçersiz kılmadığı bir derleyici hatası alırsınız.
override
özelliğin bunu "düzelttiğini" önerdiğinde, ne yazık ki, biraz kırmızı bir ringa balığı ; yazmayı hatırlamanız gerektiği gibi kullanmayı hatırlamanız gerekir const
;)
explicit
Sınıf tanımlarının C ++ 11'e girmediğini fark ettim . Huh.
explicit
Sınıf tanımlaması ne yapar? Bunu hiç duymadım.
override
bunu yapmak istediğinde çılgınca yazmak ), köşe vakalarını hatırlamaktan daha olasıdır, yani farklı prototiplerin işlevlerini kopyalama konusunda genel bir şey yoktur, sadece yerine eksik const
veya yazma gibi düzensizlikler vb.char
int
Wikipedia teklifi:
Geçersiz kılma özel tanımlayıcısı, derleyicinin bu tam imzayla sanal bir işlev olup olmadığını görmek için temel sınıf (lar) ı kontrol edeceği anlamına gelir. Ve yoksa, derleyici hata verecektir.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Düzenle (cevabı biraz geliştirmeye çalışıyor):
Bir yöntemi "geçersiz kılma" olarak bildirmek, bu yöntemin temel sınıfta bir (sanal) yöntemi yeniden yazmayı amaçladığı anlamına gelir . Geçersiz kılma yönteminin, yeniden yazmayı amaçladığı yöntemle aynı imzası (en azından giriş parametreleri için) olması gerekir.
Bu neden gerekli? Peki, aşağıdaki iki yaygın hata durumu önlenir:
yeni yöntemde bir tür yanlış yazılır. Derleyici, önceki bir yöntemi yazmak niyetinde olmadığından, yeni bir yöntem olarak sınıfa ekler. Sorun şu ki, eski yöntem hala orada, yeni yöntem aşırı yük olarak ekleniyor. Bu durumda, eski yönteme yönelik tüm çağrılar, davranışta herhangi bir değişiklik olmadan (yeniden yazmanın amacı olurdu) daha önce olduğu gibi çalışacaktır.
biri, üst sınıftaki yöntemi "sanal" olarak bildirmeyi unutur, ancak yine de bir alt sınıfa yeniden yazmaya çalışır. Bu görünüşte kabul edilecek olsa da, davranış tam olarak amaçlandığı gibi olmayacaktır: yöntem sanal değildir, bu nedenle üst sınıfa doğru işaretçilerden erişim yeni (alt sınıf ') yöntemi yerine eski (üst sınıf') yöntemini çağırmayı sona erdirir.
"Geçersiz kılma" eklemek bunu açıkça belirsizleştirir: bu, derleyiciye üç şeyin beklediğini söyler:
Bunlardan herhangi biri yanlışsa, bir hata sinyali verilir.
* Not: Çıktı parametresi bazen farklı, ancak ilişkili türde olabilir. İlgiliyse kovaryant ve kontravaryant dönüşümler hakkında bilgi edinin.
" Geçersiz kılma " seçeneği, isteğe bağlı bir parametre eklemek gibi temel sınıf sanal yöntem imzasını güncelleyen ancak türetilmiş sınıf yöntemi imzasını güncellemeyi unuttuğunda yararlıdır. Bu durumda, baz ve türetilmiş sınıf arasındaki yöntemler artık polimorfik bir ilişki değildir. Geçersiz kılma bildirimi olmadan, bu tür bir hata bulmak zordur.
override
kadar bu tür sorunları keşfetmenin harika bir yolu olsa da , iyi bir birim test kapsamı da yardımcı olmalıdır.
Evet, öyle. Birinin geçersiz kılmayı denemediğinden ve bot imzalı bir imzayla karıştırdığından emin olun. İşte bunu ayrıntılı olarak açıklayan ve kısa bir açıklayıcı örneği olan bir Wiki sayfası:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
C ++ 17 standart taslak
C ++ 17 N4659 standart taslağında tüm override
isabetlerin üzerinden geçtikten sonra , tanımlayıcıya bulabileceğim tek referans :override
5 Sanal işlev virt-specifier geçersiz kılma ile işaretlenmişse ve bir temel sınıfın üye işlevini geçersiz kılmazsa, program kötü biçimlendirilir. [ Misal:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- son örnek]
bu yüzden muhtemelen yanlış programları patlatmanın tek etkisi olduğunu düşünüyorum.