2011-06-07 17 views
16

Belirli bir static_cast'in bir sınıfın yapıcısını çağıracak olup olmadığını belirleme kuralları nelerdir? C stili/fonksiyonel stil atmalarına ne dersiniz? Uygun bir dönüşüm dönüşüm yapıcısı static_cast tarafından çağrılır kurucu varsaYayınlar, yeni türün yapıcısını ne zaman arar?

cevap

12

Yeni bir nesne oluşturulduğunda, bir kurucu çağrılır. static_cast, her zaman numaralı ya da kullanıcı tanımlı bir dönüşüme yapılan bir çağrı aracılığıyla yeni, geçici bir nesneye (ancak James McNellis'in yorumuna bakın) neden olur. (Fakat dönmek için istenen tipte bir nesne olması için, kullanıcı dönüşüm operatör bir kurucu aramak zorunda tanımlanmış olur.)

Hedef bir sınıf tipi, C stili yayınları ve fonksiyonel bir tarz kalıplar olan

Tek bir argüman ile tanım olarak static_cast ile aynıdır. Fonksiyonel stilin sıfır veya sıfırdan fazla bir argümanı varsa, o zaman derhal yapıcıyı çağırır; Kullanıcı tanımlı dönüşüm operatörleri bu durumda dikkate alınmaz. (Ve kimse olabilir soru bu a "tipi dönüşüm" çağıran bir seçim.) Kayıt, bir kullanıcı tanımlı dönüşüm operatörü denilebilir bir vaka için

:

class A 
{ 
    int m_value; 
public 
    A(int initialValue) : m_value(initialValue) {} 
}; 

class B 
{ 
    int m_value; 
public: 
    B(int initialValue) : m_value(initialValue) {} 
    operator A() const { return A(m_value); } 
}; 

void f(A const& arg); 

B someB; 
f(static_cast<A>(arg)); 

Bu özel durumda , döküm gereksizdir ve dönüşümünün olmaması durumunda örtülü olarak yapılacaktır. Ama her durumda: Örtülü dönüşüm, static_cast, C tarzı dökme ((A) someB) ya da fonksiyonel stil döküm (A(someB)), B::operator A() adı verilecek)

+2

"A" static_cast "her zaman yeni, geçici bir nesneye neden oluyor" doğru değil. Örnek olarak, sınıf hiyerarşisi struct B {}; struct D: B {}; ', aşağıdaki 'static_cast' yeni bir nesne yaratmaz:' D d; B & b (static_cast (d)); '. Hedef türün bir nesne türü olduğu herhangi bir" statik_cast ", yeni bir nesne oluşturacaktır. –

+0

@James Evet, daha hassas olmalıydım. Sınıf türlerini düşünüyordum (ilgili sorudan beri) kurucular) aslında kural basittir (ve tüm dökümler için aynıdır): eğer sonuçlar bir referans ise, yeni bir nesne yoktur, aksi halde vardır. (Standart açısından, bir tür dönüşümün sonucu ve eğer dönüşüm bir referans türüne ise, bir değerdir.) –

4

: "işlevsel" Aynı C-tarzı için geçerlidir

class Class { 
public: 
    Class(int); //<< conversion constructor 
}; 

int what = 0; 
Class object = static_cast<Class>(what); 

atmalarını ve atmalarını.

int what = 0; 
Class object = (Class)what; 

int what = 0; 
Class object = Class(what); 
+0

Ne yapıcı müstehcen olup olmadığı hakkında.? Hala çağrılacağını varsayardım. – Mankarse

+0

@Mankarse: Evet, 'açık', türü belirtmeden çağrılmayacağı anlamına gelir. Türü belirttiğinizde çağrılacak. – sharptooth

11

Bu tür yeni bir örnek oluşturulduğunda, sınıf türü için bir kurucu çağrılır. Bir yayın bu sınıf türünde yeni bir nesne oluşturuyorsa, bir kurucu çağrılır. Aşırı yük çözünürlüğü, sınıf türü için kuruculardan hangisinin belirli argümanlar verildiğini belirler.

static_cast hedef türü bir sınıf tipi ise, hedef türünün yeni bir nesnesini oluşturur. const_cast, dynamic_cast, veya reinterpret_cast, hiçbir zaman yeni bir sınıf türü nesne oluşturmayacaktır ve bu nedenle hiçbir zaman bir kurucu çağırmayacaktır. C tarzı döküm yana

daima, bir static_cast yeni bir nesne oluşturduğu aynı koşullarda yeni bir nesne oluşturur static_cast, const_cast ve reinterpret_cast bazı kombinasyonunu gerçekleştirir.

+1

Bu doğru, ancak * yeni bir örnek oluşturduğunda (* IIC işlev stili kadronun her zaman yaptığı ve statik kalemin cv-kalifikasyonundan daha fazla olduğu zaman) olduğunu söylemek önemlidir. –

+0

Yeni bir sınıf türü nesnenin oluşturulduğu tek zaman, hedef tür bir sınıf türü olduğunda "static_cast" ile olur. Cevabı bu ayrıntıyla güncelledim. –

+0

Ancak bu –

İlgili konular