2013-06-20 31 views
20

Bu kod:Neden bir uçucudan varsayılan bir kopya kurucu ile sağlanmıyor?

class X { 
    int member; 
}; 

volatile X a; 
X b = a; 

hata ile başarısız:

prog.cpp:6:7: error: no matching function for call to ‘X::X(volatile X&)’ 
prog.cpp:6:7: note: candidates are: 
prog.cpp:1:7: note: X::X() 
prog.cpp:1:7: note: candidate expects 0 arguments, 1 provided 
prog.cpp:1:7: note: X::X(const X&) 
prog.cpp:1:7: note: no known conversion for argument 1 from ‘volatile X’ to ‘const X&’ 

Benim için bir uçucu kopya kurucu oluşturmak için derleyici alabilirsiniz bir yolu var mı?

+0

İhtiyacınız “volatile” ı ilan etmek. – 0x499602D2

+0

Ama uçucu olmayan bir kopya istiyorum! – Eric

+3

'volatile X &' const X 'ye dönüştürülemez çünkü iki niteleyici birbiriyle çelişir: 'const'' bir kez okur, değişmeyecektir ',' volatile' diyor ki 'her seferinde okuyor, çünkü değişebilir". C++ standardında bu dönüşümü dolaylı olarak yasaklayan bazı akıllı kurallar olmalıdır. – dasblinkenlight

cevap

14

Kısa cevap şu ki: Çünkü standart yapamayacağınızı söylüyor.

C++ Standardı 12.9/8 (Taslak N3242) anlatıyor:

The implicitly-declared copy constructor for a class X will have the form

  • X::X(const X&)

if

  • each direct or virtual base class B of X has a copy constructor whose first parameter is of type const B& or const volatile B&, and
  • for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy constructor whose first parameter is of type const M& or const volatile M&. [Note: 119]

Otherwise, the implicitly-declared copy constructor will have the form

  • X::X(X&)

Not 119 diyor ki:

C.1.9 In

This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue; see C.1.9.

şunları bulacaksınız:

The implicitly-declared copy constructor and implicitly-declared copy assignment operator cannot make a copy of a volatile lvalue. For example, the following is valid in ISO C:

struct X { int i; }; 
volatile struct X x1 = {0}; 
struct X x2(x1); // invalid C++ 
struct X x3; 
x3 = x1; // also invalid C++ 

Rationale: Several alternatives were debated at length. Changing the parameter to volatile const X& would greatly complicate the generation of efficient code for class objects. Discussion of providing two alternative signatures for these implicitly-defined operations raised unanswered concerns about creating ambiguities and complicating the rules that specify the formation of these operators according to the bases and members.

-3

Önemli sorun, atama yapıcısı sağlamanızdır. Sonuç olarak, derleyici bir varsayılan sizin için biri oluşturmak:

X& X::operator =(const X& x){ 
    this.member = x.member; 
    return *this; 
} 

varsayılan atama kurucu const olarak argüman türünü kabul X & hangi const 'bir düşük seviyeli const ve kazandı üst düzey const olarak göz ardı edilmemelidir.

X b = a kodunuz, varsayılan yapıcıyı çağırmak anlamına gelir. Ama argüman aKat örtülü X & dönüştürülebilir olamaz (uçucu X & ve uçucu const X & dönüştürülebilir) uçucu X yazın sahiptir.
O kadar çok çocuklar kopya yapıcısı (veya kopya başlatma diyoruz) düşünüyorum beni şok olduğunu

X& X::operator =(volatile const X&); 

DÜZENLEME olarak

Yani kendi atama kurucusu tanımlamak gerekir atama operatörü kullanıldığında çağrılır. Belki de atama operatörü genel olarak adlandırılamıyor. Ancak, umurumda olan hangi yöntem denir.

Bu mesaja bakabilirsiniz: Copy constructors, assignment operators, and exception safe assignment ve Default assignment operator


DÜZENLEME
Daha önce bir hata yaptım. X b = a sadece bir başlatma işlemidir. Ödev yapılmadı. Hata mesajım için özür dilerim.

+3

Hayır. X (volatile const X & x) gibi bir kurucu: 'X b = a' 'kopyası başlatıldığından beri üye (x.member) {}' gereklidir. "Görev yapıcı" gibi bir şey yoktur. Bir kurucu veya bir atama operatörü vardır. – Pixelchemist

+0

@Pixelchemist Sağladığınız şeye "copy constructor" denir. Bu ikisi farklı şeyler. C++ 'da ** üç kuralı denir. – Zachary

+0

Üçüncüsü, temel olarak kaynakları yöneten sınıflar için geçerlidir. Bu durumda, volatil X'den X'e dönüşüm yapmak için açık olmayan bir kopya kurucusu gereklidir. – Pixelchemist

İlgili konular