Topic: N1582 and protected compiler generated copy constructor


Author: "AndyRB" <xandyrb@hotmail.com>
Date: Sat, 24 Dec 2005 08:19:48 CST
Raw View
Regarding implementing clone I was thinking it would be nice if you
could declare the default copy-constructor as protected and proposal
N1582 would /potentially/ seem to support this*.

* The proposal actually says, "The rules for compiler generation of the
four members are as they are for the generation of the implicit
versions.", which seems to imply that any compiler generated copy
constructor would in fact be inline and /public/.

There are many times when the default copy constructor does exactly
what is required and in those cases this greatly simplifies copying in
C++. When an object is polymorphic, implementing clone in terms of the
copy constructor makes it into a simple one-liner.

The problem with public copy constructors (where the object is
polymorphic) is slicing and because of this it often makes sense to
declare the copy constructor as protected. There are many cases when
the default copy constructor would have done "the right thing", even in
polymorphic classes, as long as the most derived copy constructor is
called.

Therefore, the problem is that if you want a protected copy constructor
that only does what the default copy constructor does, currently you
have to define it yourself.

Modified example from N1582 implementing clone in terms of compiler
generated protected copy constructors:-

explicit class example
{
  protected:
    default example(const example& other);
  public:
    default example();
    example(int * i_ptr):val(*i_ptr){}
    default virtual ~example();
    virtual example * clone() { return new example(*this); }
  private:
    int val;
};

class derived: public example
{
  protected:
    default derived(const derived& other);
  public:
    virtual derived * clone() { return new derived(*this); }
    // other public interface members
  private:
    std::string s;
};

int main(){
  int i(12);
  example e1; // OK, uses compiler generated default
  example e2(&i); // OK uses second constructor
  example e3(e1); // ERROR no public copy ctor
  derived d1; // OK
  derived d2(d1); //ERROR, no public copy ctor
  example* d1_ptr = new derived;
  example* d2_ptr = d1_ptr->clone(); //clone uses compiler generated
                                                     //protected copy
constructor
  delete d1_ptr; // calls an implicitly generated
                     // ~derived() first which calls ~string
  delete d2_ptr;
}

Is it intended that N1582 should allow this and also is there any news
on whether N1582 will appear, with or without this ability, in the next
standard?

Cheers.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]