Copy constructor is not inherited

后端 未结 3 844
感动是毒
感动是毒 2020-11-28 12:16

I\'ve got the following code:

class C {
public:
    C(int) {}
    C(const C&) {}
    C() {}
};  

class D : public C { 
public:
    using C::C;
};  

int         


        
相关标签:
3条回答
  • 2020-11-28 12:39

    Derived class should inherit all ctors of base except the default ctor

    No, that's not true, see T.C.'s answer for the real rule.

    The purpose of inheriting constructors is to say "the derived type can be created from the same arguments as the base type", but that isn't relevant for the base class' copy constructor, because a copy constructor is not just a way of saying how to create a type from a given argument.

    A copy constructor is special, it's for copying an object of the same type.

    A constructor D(const C&) would not used be for copying an object of the same type, because C is not the same type as D.

    0 讨论(0)
  • 2020-11-28 12:49

    Because the standard says so. [class.inhctor]/p3, emphasis mine:

    For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the complete class where the using-declaration appears or the constructor would be a default, copy, or move constructor for that class.

    0 讨论(0)
  • 2020-11-28 12:57

    For a moment, we’ll assume ‘copy constructor inheritance’ is allowed. Having your class structure intact, please consider following code for modified main method.

    int main() {
        C c;
        D d;
        D d_from_d(d);
        D d_from_c(c); // does not compile, copy ctor is not inherited
        D d_from_int(1); // compiles, C(int) is inherited
    }  
    

    In D d_from_d(d), as a normal constructor call, there will be two copy constructor calls. One for C::C(const C&) and the other one is for compiler generated copy constructor for D. Having source object type in D (d in this case), C’s copy constructor can copy d’s C attributes while compiler generated D’s copy constructor can copy d’s D attribute.

    But in D d_from_c(c) case, There is no problem for C’s copy constructor because, c’s C attributes can be copies by C’s copy constructor. But how does the compiler generated D’s copy constructor know the way to copy ‘D’s attributes from C’s object’. This is a conflict which should be avoided.

    But, if you provide some sort of ‘weird copy constructor’ (you may need to a default constructor as well) like;

    D(const C & c):C(c){} 
    

    Then, calling D d_from_c(c); is valid. Because, now we have explicitly provided a matching ‘copy’ constructor.

    So, saying ‘Inheriting copy constructors are now allowed’ is invalid.

    0 讨论(0)
提交回复
热议问题