2011-06-07 31 views
14

Saf bir sanal işleve sahip olmanın yanı sıra soyut bir temel sınıfın bir örneğini engellemenin bir yolu var mıdır?C++: soyut bir temel sınıfın herhangi bir örneğini önlemek için herhangi bir yol?

class BaseFoo 
{ 
    virtual void blah() = 0; 
}; 

class Foo : public BaseFoo 
{ 
    virtual void blah() {} 
}; 

ama VTable önlemek istiyorum:

Bunu yapabilirim.

Microsoft ATL ATL_NO_VTABLE sahiptir (my other question about virtual destructors göre) Bunu başarmak (veya en azından bunun ne işe yaradığını düşünüyorum ...)

+2

Neden vtable'lardan kaçınmak istiyorsunuz? (Ve yöntem sanal olduğu gerçeği kullanmayacaksanız, neden bir temel sınıf ile rahatsız ediyorsun?) \ –

cevap

34

Gerçekten bariz yolu korumalı bir yapıcısı ilan etmek ve ortak kurucular ilan etmek için soyut olmayan türetilmiş sınıflarda. Bu, tabii ki, bozulma yükünü türetilen sınıflara kaydırır, fakat en azından temel sınıf korunur. Burada tavsiye gibi korumalı bir yapıcısı yaparsanız sizin türetilmiş sınıf Eğer bir hata benzer alırsınız inşa edildiğinde

+0

Güzel. Ama belki de "gerçekten bariz" ;-) – Johnsyweb

+3

Eh, delice şablon kesmek ile karşılaştırıldığında bariz insanların beklemek bekliyordum! – Blindy

+0

Tamam, açık senin için :-) – Johnsyweb

5

Sen "sınıfta bildirilen özel üye erişemez", o zaman, korumalı bir yapıcısı

-4

yapabiliriz, sınıflarınıza özgü diğer bilgilerle.

Temel sınıfınızda saf sanal yöntemleriniz varsa, o zaman sorun bunların örneklenmemiş olması (ve kesinlikle soyut olmayan yöntemlerin örneklendirilmesi değildir), ancak sorun, derleyici aşağıdakileri gerçekleştirdiğinde imha etme zamanında gerçekleşir. türetilmiş sınıfınızın sahip olduğu sonucu çıkarmaz. Bu, ya da bir sahibi olmadan bir şeyler var! (ruh roh rhaggy)

Temel sınıfınız için saf bir sanal yıkıcıyı bildirin ve sonra bunu harici olarak uygulayın. Ayrıca, asla bir kurucu özel yapmayın (düzenleme: yalnızca içsel olarak kullanılmadığı sürece, bağlantılı listedeki bir sonraki düğümün otomatik olarak oluşturulması gibi). En yakın istediğiniz (düzenleme: aksi halde), açık bir kurucu (ama başka bir konu) 'dir.

düzenlemeleri: Cevabı bulmuş olabilir, ancak yine de bugün yazamam.

// example.h 

class A 
{ 

    A () { } 
    virtual ~A () = 0; 
}; 

class B : public A 
{ 
    B () { } 
    ~B () { } 
}; 

// example.cpp 
#include "example.h" 

A::~A () { } 
+1

'** Korumalı ** kurucu yaparsanız ... bir hata yakalayın ... "** özel ** üye erişemezsiniz."? Kurucu "korumalı" değil "özel" ise türetilmiş bir sınıfta, özel bir üye olmadığından özel bir üyeye erişmenizi söyleyen herhangi bir hatayı almayın: – Pixelchemist

+0

Bu "yanıt" (diğer bir deyişle, gerçek cevaplar hakkında bir yorum) yanlıştır. – Blindy

İlgili konular