开发者

Object oriented programming , inheritance copy constructor

Suppose i have a base class "person". and i publically inherits a class "student " from the base class "person". i have not written the copy constructor for base and the derived class. now suppose i write in the main program

main()
{
student sobj1("name", "computer science");
student sobj2=sobj1;
}

now in the second line the default compiler generated copy constructor 开发者_运维技巧of the student will be called but before the execution the default copy constructor of the base class will be called which creates an anonymous object and initialize it then control comes back to the copy constructor of the student which initialize the student's portion of the object.

this is the demonstration for the situation where we don't write the copy constructor

now suppose we write the copy constructor for both the classes , then i have tested that when i write

student sobj2=sobj1;

what happens is , this line calles the copy constructor of the student which works , but the copy constructor of the bases class will not be called in this case(default constructor of the base class will be called) my question is why?


vava almost has his rules correct, here's a more explicit version:

  • You cannot have an instance of a derived class without first constructing base class subobjects: all bases' ctors execute first. (Ctor is shorthand for constructor.)
  • You cannot enter the body of a ctor without first constructing each member of that class: all members' ctors execute after bases' ctors.
  • The compiler generated default ctor uses default ctors for bases and members.
  • The compiler generated cctor does member-wise copy: all copy ctors for bases and members are used. (Cctor is shorthand for copy constructor.)
  • The compiler generated assignment operator does member-wise assignment: the assignment operator for bases and members is used. (The assignment operator is also called operator= and op=.)
  • When implementing a ctor yourself (any ctor, including a copy ctor), any base or member without initialization parameters will use its default ctor (in the ctor initializer, the part with the colon and before the ctor's function body).
  • If a data member's default ctor is trivial (more or less "if it's compiler-generated") and you do not specify that member in the ctor initializer, then the value of that member will be garbage.
    • This points out how these rules still over-simplify; see 12.6.2/3-4 in the C++ standard for the exquisite details.
    • This only applies to data members with trivial default ctors.
    • Base classes with trivial default ctors are always garbage.

vava's example of specifying Person's copy ctor is completely correct:

struct Student : Person {
  Student(Student const& other) : Person(other) {}
};

Examples of the last bullet:

struct TrivialCtor { int n; };
struct A {
  TrivialCtor m;
  A() {}          // m.n is garbage
  A(int) : m() {} // m.n is 0

  friend ostream& operator<<(ostream& s, A const& v) {
    s << "m.n = " << v.m.n;
    return s;
  }
};

int main() {
  cout << "()   : " << A() << '\n';
  cout << "(int): " << A(42) << '\n';
  return 0;
}


I believe the rules are following:

  1. Constructor of base class always should be called before constructor of derived class.
  2. You can choose which one of base class constructors will be called by calling it explicitly in initialization list.
  3. If you do not do that, default constructor is called.
  4. When class has no copy constructor, compiler generates one instead. It will call default constructors for all the members of the class and copy constructor of base class, just as your hand written constructor actually should.

So, there you go. Unless you call copy constructor of base class, default one will be used BUT compiler is smart enough to actually call it in it's own generated copy constructor.

Just in case you do not know how to call it, there example

Student(Student const & p): Person(p) {
}


Roger and vava have answered your technical question.

However, you may not be aware of it now, but you do not want to support copy on objects from a polymorphic hierarchy of classes.

First of all because it makes no sense to copy entities. What is the meaning of copying a student? None!

Secondly, you'll have to struggle with slicing when copying a student into a person and then back into a student. And you'll have to use workarounds to support assignment -- the Envelop-letter Idiom being the most well known.

Just inhibit copy and assignment in your base classes with by inheriting from a class like boost::noncopyable (for a pure C++98/03 solution), and handle you entities through pointers. If for some strange reason you do really need to duplicate entities, have a look at the usual clone() function that'd rely on protected copy constructors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜