2012-02-07 17 views
31

A'un temel sınıf ve'dan B türetimlerinin olduğu bir sınıf hiyerarşisi düşünün.Neden örtülü kopya oluşturucu, temel sınıf kopyalama yapıcısını çağırır ve tanımlı kopya kurucusu çalışmıyor?

Kopya kurucusu, B'da tanımlanmamışsa, derleyici bir tanesini sentezleyecektir. Çağrıldığında, bu kopya kurucusu temel sınıf kopyalama kurucusu'u (kullanıcı tarafından sağlanmamışsa, sentezlenen bile olsa) çağırır.

#include <iostream> 

class A { 
    int a; 
public: 
    A() { 
     std::cout << "A::Default constructor" << std::endl; 
    } 

    A(const A& rhs) { 
     std::cout << "A::Copy constructor" << std::endl; 
    } 
}; 

class B : public A { 
    int b; 
public: 
    B() { 
     std::cout << "B::Default constructor" << std::endl; 
    } 
}; 

int main(int argc, const char *argv[]) 
{ 
    std::cout << "Creating B" << std::endl; 
    B b1; 
    std::cout << "Creating B by copy" << std::endl; 
    B b2(b1); 
    return 0; 
} 

Çıktı:


kullanıcı B kendi kopya kurucu tanımlıyorsa

Creating B 
A::Default constructor 
B::Default constructor 
Creating B by copy 
A::Copy constructor 
, çağrıldığında, bu kopya yapıcı bir çağrı sürece, temel sınıf varsayılan yapıcı arayacak temel sınıf kopya kurucusu açık bir şekilde mevcuttur (örneğin başlangıç ​​listesinde).

#include <iostream> 

class A { 
    int a; 
public: 
    A() { 
     std::cout << "A::Default constructor" << std::endl; 
    } 

    A(const A& rhs) { 
     std::cout << "A::Copy constructor" << std::endl; 
    } 
}; 

class B : public A { 
    int b; 
public: 
    B() { 
     std::cout << "B::Default constructor" << std::endl; 
    } 
    B(const B& rhs) { 
     std::cout << "B::Copy constructor" << std::endl; 
    } 
}; 

int main(int argc, const char *argv[]) 
{ 
    std::cout << "Creating B" << std::endl; 
    B b1; 
    std::cout << "Creating B by copy" << std::endl; 
    B b2(b1); 
    return 0; 
} 

Çıktı:

Creating B 
A::Default constructor 
B::Default constructor 
Creating B by copy 
A::Default constructor 
B::Copy constructor 

Sorum, neden kullanıcı tanımlı kopya yapıcı varsayılan davranış olarak temel sınıf kopya kurucu çağırmaz mı?

+2

Varsayılan olarak böyleyse, bunun olmasını istemeyeceğiniz durumu nasıl belirlersiniz? Başlatıcı listesinde – PlasmaHH

+0

@ PlasmaHH 'ParentClass()'. Bu yine de tutarsız ve kafa karıştırıcı olabilir inanıyorum. –

+0

@MarkB: Gerçekten de, bunu düşünürken aynı sonuca varmayı umuyordum ... – PlasmaHH

cevap

7

Bu, örtük kopya oluşturucunun tanımlandığı yoldur (varsayılanı çağırmak mantıklı olmaz). Herhangi bir yapıcıyı tanımladığınız anda (kopyalayın veya başka bir şekilde) normal otomatik davranışı varsayılan üst yapıcıyı çağırmaktır, bu nedenle belirli bir kullanıcı tanımlı kurucu için bunu değiştirmek tutarsız olacaktır.

1

Basit (muhtemelen yazılan) cevap, bunu söylemediğin içindir. Türetilmiş kopya kurucuyu yazdığınız için, nasıl davrandığını tamamen kontrol edersiniz. Tabana ve derleyiciye bir çağrı belirtilmezse, temel sınıf varsayılan yapıcıyı çağırarak temel sınıfı başlatmak için kod oluşturur.

8

Tüm temel alt yapıcılar, üst varsayılan yapıcıyı çağırır. Standart tanımlanmış budur. Eğer açıkça derleyici her farklı yapıcısı için bilemeyiz çünkü

#include <iostream> 

class A { 
int a; 
public: 
A() { 
    std::cout << "A::Default constructor" << std::endl; 
} 

A(const A& rhs) { 
    std::cout << "A::Copy constructor" << std::endl; 
} 
}; 

class B : public A { 
int b; 
public: 
B() { 
    std::cout << "B::Default constructor" << std::endl; 
} 
B(const B& rhs):A(rhs) { 
    std::cout << "B::Copy constructor" << std::endl; 
} 
}; 

int main(int argc, const char *argv[]) 
{ 
std::cout << "Creating B" << std::endl; 
B b1; 
std::cout << "Creating B by copy" << std::endl; 
B b2(b1); 
return 0; 
} 

Bu böyledir sormak zorunda A'nın kopya kurucu çağırmak için temel sınıf B isteseydi Sizin de belirttiğiniz gibi hangi ebeveynin constuctor gerektiği çağrılabilir ve dolayısıyla varsayılan kurucularımız var Diğerleri için açıkça belirtmeniz gerekir.

+5

'Tüm temel alt yapıcılar, varsayılan kopya oluşturucu :) haricinde üst varsayılan yapıcıyı çağırırlar! –

+0

Kapalı kopya oluşturucu, derleyici tarafından sağlanan en ilkel işlem için açık bir addır, kaynağın hedefe bitsel kopyası. IMO sadece süslü bir isim. – shakthi