2014-10-09 31 views
6

Bildiklerim

Geçici bir nesnenin const referansı döndürmesinin tamam olduğunu biliyorum! (Bu örnekte :)alt sınıfın const başvuru başvurusu

class A { 
public: 
    virtual const A& clone() { return (A()); } 
    virtual std::string name() const { return ("A"); } 
}; 

Returning temporary object and binding to const reference

Ama böyle! Bunu yapmak istiyorum istiyorsanız

, Hala doğrudur:

class B : public A { 
public: 
    virtual const A& clone() { return (B()); } 
    virtual std::string name() const { return ("B"); } 
}; 

evet düşünürdüm, ama yürütme zamanında iade nesne hala sayılır bir bu örnekte olduğu gibi, bir nesne (:)

main.cpp

#include <iostream> 
#include <string> 
int main() { 
    B bb; 
    A* aa = &bb; 

    std::cout << aa->clone().name() << std::endl; 
} 

çıkış

valgrind ./a.out 
==14106== Use of uninitialised value of size 8 
==14106== at 0x401BF9: main (main.cpp:8) 
==14106== Uninitialised value was created by a stack allocation 
==14106== at 0x401BF2: main (main.cpp:8) 
B 

Bu yay .. B var .. ancak bu uyarı oldukça horrifing olduğunu ....

düzenle benim hatasını gördüğünü biliyorum size

Teşekkür ... ama başka şeyler bilmek istersiniz hakkında ...

Bu yürütüldüğünde, yığınta tam olarak ne oluyor?

+0

@Chris Drew ... errrh Anlamıyorum – CollioTV

+3

"Geçici bir nesnenin bir const başvuru döndürmesinin tamam olduğunu biliyorum!" Hayır değil. –

+2

http://stackoverflow.com/questions/11560339/returning-temporary-object-and-binding-to-const-reference "Bu bir C++ özelliğidir. Kod geçerli ve tam olarak göründüğü gibi görünüyor.", "C++, geçici bir nesneyi yığında bulunan bir referansa bağlanmanın referansın ömrü boyunca geçici olarak ömrünü uzattığını kasıtlı olarak belirtir" – CollioTV

cevap

12

Bir referansı geçici olarak bağlamak, geçici olma ömrünün süresini uzatır. §12.2 [class.temporary]/p5, vurgu eklendi:

olan referans bağlı olduğu geçici ya da referans bağlı olduğu bir altnesnesi tam amacı, yaşam boyunca direnen olduğu geçici dışında referans: bir şantiye ctor-başlatıcısı (12.6.2) 'de bir referans elemanına

  • geçici bağlı yapıcı çıkar kadar devam eder.
  • Bir işlev çağrısında (5.2.2) bir referans parametresine geçici olarak bağlı olan çağrı, aramayı içeren tam ifade tam ifade tamamlanana kadar devam eder.
  • Bir işlev döndürme deyiminde (6.6.3) döndürülen değere geçici olarak bağlı olan ömür uzatılmaz; Geçici, tam ifade ifadesinin sonunda iade ifadesinde imha edilir.
  • bir yeni başlatıcı (5.3.4) 'de bir referans geçici bağlı yeni başlatıcı içeren tam ifade tamamlanmasına kadar devam eder.

sen bağlantılı soruya (std::string foo(); const std::string & s = foo();) durumda Tamam; foo() tarafından döndürülen geçici sürenin ömrü, s'un ömür boyu sona ermesine kadar uzatılır. Kodunuzda, geçici olarak döndürülen değere bağlıdır ve yukarıdaki üçüncü mermi noktası başına, ömrü uzatılmaz ve işleviniz sarkan bir başvuru döndürür.

Genellikle, clone() işlevleri, bir işaretçi, bir yığın-ayrılmış kopyaya bir işaretçi döndürmelidir.

+0

Ve bunu yapmak için kodumu değiştirdim! Teşekkürler! – CollioTV

+0

@ T.C. Peki, bu * bir alt sınıfına (veya üye var) bir const başvuru döndüren bir yöntem varsa ne olur? Arayan, referansın yöntemin çağrıldığı nesneyi geçmediğinin farkında olmalıdır; ve eğer bu nesne bir geçiciyse, dil, bu kurallar tarafından ömrünü uzatmaz, çünkü referans çağrı kodunda değil, yöntemde alınmaz. Doğru? – greggo

İlgili konular