2010-12-06 40 views
5

I g herhangi bir uyarı (-Wall -pedantic) ++C++ bir const std :: string &?

#include <iostream> 
#include <string> 

using namespace std; 

class Foo 
{ 
public: 
    Foo(const std::string& s) : str(s) 
    { } 

    void print() 
    { 
     cout << str << endl; 
    } 

private: 
    const std::string& str; 
}; 


class Bar 
{ 
public: 

    void stuff() 
    { 
     Foo o("werd"); 
     o.print(); 
    } 
}; 


int main(int argc, char **argv) 
{ 
    Bar b; 
    b.stuff(); 

    return 0; 
} 

Ama bunu çalıştırmak sadece satır yazdırılır ile derler aşağıdaki kodu vardır. Neler oluyor? Bu iç şeyler yapmak olsaydı

:

string temp("snoop"); 
Foo f(temp); 
f.print(); 

o zaman çalışıyor! aslında başlık altında şu şekilde derler çünkü

cevap

18

Bu başarısız nedeni budur. Bu durumda

Foo o(std::string("wurd")); 

Foo değeri yapıcı tamamlandıktan sonra silinir geçici nesnesine bir başvuru alıyor. Bu yüzden ölü bir değerde tutuyor. İkinci sürüm, Foo örneğinden daha büyük bir ömre sahip olan bir yerel için bir başvuru tuttuğu için çalışır.

bir const std::string bir const std::string& olmaktan bu değişikliği memebr düzeltmek için.

+0

şerefe, beynim o elde değildi neden bilmiyorum: parametre olarak bir const değerini alarak bir anlamı yok –

+0

s. Sadece 'std :: string' kullanın. –

+1

@MilesRout Bu tamamen doğru değil. Dizeyi değiştirmek istemediğinizi biliyor olabilirsiniz ve const'ı bildirerek derleyicinin bunu yapmadığınızı doğrulamasına izin vermiş olursunuz. – Erik

2

oluyor nedir geçici arg, 's' işaret eden bir referans str başlatıldı olmasıdır. Bir işaretçiyi kullanmakla hemen hemen aynı - yapıcı argümanınızın devam eden varlığına güveniyorsunuz, 's'. Geçici silindiğinde (yapıcı ftn geri döndükten sonra), referansınız artık çöp kutusuna işaret eder. onun gerçek bir dize nesne değil, bir referans olacak şekilde

, değişim str düzeltmek için.

const std :: string str;

bir kopyası arg dize yapılan ve kopya Foo nesne olarak aynı ömre sahip olacak söylenebilir Bu şekilde.

İlgili konular