2016-01-17 28 views
9

Neden C++, bir sınıf bildirimi içinde tanımlanabilmesi için yalnızca integral türlerin ve enum'un (enum'un ayrılmaz bir tür olduğunu) anlamıyorum. Kayan nokta türleri de dahil olmak üzere tüm diğer tipler (yani, çift ve yüzdürme), sınıf beyanı dışında tanımlanmak zorundadır. Açıkçası bunun bir nedeni olmalı, ama anlayamıyorum.Neden C++ sınıfında yalnızca integral veya enum türü başlatılabilir?

Kod örnek:

#include <iostream> 

using namespace std; 

struct Node { 

    static const int c = 0; // Legal Definition 
    static const long l = 0l; // Legal Definition 
    static const short s = 0; // Legal Definition 

    static const float f = 0.0f; // Illegal definition 
    static const string S = "Test"; // Illegal definition 

    static const string JOB_TYPE; // Legal declaration 
    static const float f; // Legal declaration 
    static const double d; // Legal declaration 
}; 

const string Node::JOB_TYPE = "Test"; // correct definition 
const float Node::f = 0.0f; // correct definition 
const double Node::d = 0.0; // correct definition 

int main() { 

    cout << Node::c << endl; 
    cout << Node::c << endl; 

    cout << Node::JOB_TYPE << endl; 

    cout << Node::f << endl; 

} 
+0

Bir düğümde 'Düğüm' yapısını koyarsanız ve 2 dosyaya eklerseniz sorun yaşarsınız. –

+1

Bu çok güzel bir soru - Bu pazar günü beyin hücrelerini aldım. Teşekkürler –

+2

Kayan noktalara özgü kurallar genellikle çapraz derleyicilerle ilgili kaygılar, yani bir sistem üzerinde çalışan ancak başka bir kod üreten derleyicilerdir. Hedef sistemle eşleşen entegre tiplerle başa çıkmak için yeterince kolaydır; Başka bir sistemin kayan nokta türlerinin ayrıntılarını almak çok daha karmaşıktır. –

cevap

8

Burada anahtar nedeni ayrılmaz türleri (ve enum çünkü derleyici içinde bunların çeşit tamsayılar olmak) trivially yerini ve sabitler olarak doğrudan kullanılabilir olmasıdır.

Başka bir deyişle, S::x derleyici struct S { static const int x = 42;} görüyorsa, derhal üretilen kodu 42 sabitiyle değiştirin. Aynı şey (her zaman)için geçerli değildir ve kesinlikle std::string gibi kurucuya bağımlı olmayan türler için geçerli değildir - derleyici,(veya std::string::allocator) numaralı çağrıları yapmadan std::string için bellek ayıramaz. Bu yüzden, "yapılandırılmış" olması ve/veya nasıl kullanılabileceği konusunda daha karmaşık kriterler olması gereken sabitler için (kayan nokta için donanım desteğine sahip olmayan bir işlemci düşünün - kayan nokta değerlerini yüklemek ve saklamak için işlev çağrıları, vb), dil bunu yapmasına izin verilmesi gerektiğini belirleyemez.

static const std::string S = "test"; ile struct Node bildirimi eklerseniz, derleyici Node::S deposunda kaç yerde saklanır? En çok üç çeviri biriminizi bir programa bağladığında hangisini kullanmalı, yoksa farklı olanları mı kullanmalı? const_castNode::S ile karşılaşırsanız ve değiştirirseniz ne olur? İkincisi, bunun bir kazaya neden olmadığı, tamamen makul olan bir ortam olduğunu varsayar ve bu tanımlanmamış bir davranış olsa da, derleyicinin onu her bir çeviri biriminde farklı değerler kullanması kadar garip yapması gerektiğinden emin değilim. bu durumda ...

Düzeltme: Açıklamalarda belirtildiği gibi, C++ 11, daha fazla türün benzer şekilde kullanılmasına izin verir, böylece derleyici ve donanım teknolojisi geliştirilirken kısıtlamalar gevşer. static const std::map<X, Y> a = { ... } tho 'yapabildiğinizden şüphe duyuyorum, çünkü çok karmaşık bir veri türü oluşturmak için ...

+0

"Buradaki temel neden, tümleşik türlerin (ve derleyici içinde bunların bir tür tamsayı haline gelmesidir) en önemsiz şekilde değiştirilebilmeleri ve doğrudan sabit olarak kullanılabilmeleridir." Daha genel olarak, bu türdeki türler kullanılabilir. yol - belki de kuralın bunlara yer vermek için rahat olacağını umuyoruz? –

+0

Sorun, editörlerin kayan nokta değerleri de olabilir (başkalarının da var olup olmadığından emin olmamakla birlikte) ve genellikle özel bir işlem gerektiriyorlar - özellikle kayan nokta için yerleşik desteğe sahip olmayan donanımlarda. –

+1

@ChrisBeck "rahatlayacak" -> "rahat". http://melpon.org/wandbox/permlink/1qxlfeqKMVWoeti7 ve daha genel olarak, tüm edebi türler, [class.static.data] p3 – dyp

0

std::string'un başlatılması, çalıştırma sırasında bazı kodların çalıştırılmasını gerektirir.

Dize değişmezine sahip bir işaretçiyi ilklendirmek, dizgeyi bellekte de, çalışma zamanında da yerleştirmeyi gerektirir.