2010-06-03 31 views
5

bir nesne const nesne veya düzenli nesne olup olmadığını bilmenin bir yolu örneğin kullanıcı String bir const nesne oluşturmak o zaman hiçbir orada aşağıdaki sınıfconst nesne ve const yapıcı

class String 
{ 
    String(const char* str); 
}; 

düşünün var mı Aktarılan yerel dizeyi kopyalama nedeni ve üzerinde herhangi bir değişiklik yapmayacağı için, yapacağınız tek şey dize boyutunu, dize aramasını ve dizeyi değiştirmeyecek diğer işlevleri almaktır.

+5

Bilmenin bir yolu yok. Aslında, 'const' yalnızca nesne başlatıldıktan sonra (yapıcı bitirir) ve yıkıcı girildiğinde durur. – GManNickG

cevap

8

Kopyalama için çok iyi bir neden var - const char * öğesinin ömrünün String nesnesininkiyle aynı olduğunu bilemezsiniz. Ve hayır, bir const nesnesi oluşturduğunuzu bilmenin bir yolu yoktur.

2

Ne yazık ki, C++, denediğiniz şeyi yapmak için bir yol sağlamaz. Sadece bir const char * geçirilmesi, belleğin işaret ettiği kullanım ömrünü garanti etmez. Şunları düşünün:

char * a = new char[10]; 
char const *b = a; 
String c (b); 
delete[] a; 
// c is now broken 
2

Bilmeniz için bir yolu yoktur. String ile sıkı bir şekilde etkileşime giren ve harici bir arabelleğe işaret eden sabit bir dize oluşturan bir sınıf yazabilirsiniz (ilgili kurucuyu özel yaparak ve etkileşimli sınıfı yuvalanmış bir sınıf veya String'un bir arkadaşını yaparak).

Endişelenmeniz gereken tek şey, potansiyel olarak küçük bir sabit dizede dinamik bellek yönetimi yapmaksa, Küçük Dize Optimizasyonunu (ayrıca Küçük Nesne/Arabellek Optimizasyonu) da uygulayabilirsiniz. Dize sınıfınızda gömülü bir arabelleğe sahip olmak ve her dizeyi bu arabelleğe önceden tanımlanmış bir boyuta kopyalamak ve dinamik olarak ayrılmış bir depolamaya daha geniş olan her dize (aynı teknik, küçük boyutlu işlev nesnelerini depolamak için boost::function tarafından kullanılır) çalışır. .

class String { 
    union { 
    char *dynamicptr; 
    char buffer[16]; 
    }; 
    bool isDynamic; 
}; 

tampon kendisine hatta gömülü dize uzunluğunun depolanması için (buffer[15] ve benzeri hilelerinin olarak uzunluğunun depolanması için) için akıllı teknikler vardır.

0

Aradığınız şey temelde bir COW (kopyalamada) dizesidir. Bu tür şeyler tamamen mümkündür, ancak onları çalışmak için kuyu biraz önemsiz değildir. Çok iş parçacıklı bir ortamda, iyi bir performans elde etmek, önemsiz olanın ötesine geçen zorlu aralığa çıkabilir.

1

Aradığınız şeyi yapmak için const_string'i kullanabilirsiniz. Ancak, const dizgisiyle bile, dizenin kopyalanması gerekmediğini "söylemeniz" gerekir.

const char* foo = "c-string"; 
boost::const_string bar(foo); // will copy foo 
boost::const_string baz(boost::ref(foo)); // assumes foo will always be a valid pointer. 
1

Dize sonra üzerine herhangi manipülasyon yapmayacağız çünkü o yapacak tek şey dize boyutunu almak olduğunu ve geçirilen yerli dize kopyalamak için hiçbir neden yoktur kullanıcı bir const nesne oluşturmak durumunda , dize arama ve dizgeyi değiştirmeyecek diğer işlevler.

Evet var. Sadece const olarak geçer, const yapıcı çağrısının dışında const olduğunu ve özellikle dize nesnesi hala yokken yok olmayacağı anlamına gelmez. Bir işlev argümanı için const anahtar kelimesi, yalnızca işlevin değiştirilmeyeceği veya silinmeyeceği anlamına gelir (const argümanını değiştiren bir fonksiyonun derleyici hatasıyla sonuçlanmasına neden olur), ancak işlevin dışarıda ne olduğunu bilmesinin bir yolu yoktur. .