copy control in derived class

C

campos

"Effective C++ 3rd Edition" Item 6, P39

-------------------------------------------------------

class Uncopyable {
protected: // allow construction
Uncopyable() {} // and destruction of
~Uncopyable() {} // derived objects...
private:
Uncopyable(const Uncopyable&); // ...but prevent copying
Uncopyable& operator=(const Uncopyable&);
};

To keep HomeForSale objects from being copied, all we have to do now is
inherit from Uncopyable:

class HomeForSale: private Uncopyable { // class no longer
... //
declares copy ctor or
}; // copy
assign. operator

-------------------------------------------------------

I understand that the copy ctor and copy assignment of class
HomeForSale will be implicitly generated by the compiler if needed. In
the copy ctor of HomeForSale, first it will call the default ctor of
Uncopyable implicitly. As for copy assignment, it won't call the
counterpart in the base class.


But why the author says:

-------------------------------------------------------
This works, because compilers will try to generate a copy constructor
and a copy assignment operator if anybody - even a member or friend
function - tries to copy a HomeForSale object. As Item 12 explains,
the compiler-generated versions of these functions will try to call
their base class counterparts, and those calls will be rejected,
because the copying operations are private in the base class.
-------------------------------------------------------

I tried it in VC7.0 and it did come out with a compiled error instead
of a link error.

Thanks in advance!
 
J

Jim Langston

campos said:
"Effective C++ 3rd Edition" Item 6, P39

-------------------------------------------------------

class Uncopyable {
protected: // allow construction
Uncopyable() {} // and destruction of
~Uncopyable() {} // derived objects...
private:
Uncopyable(const Uncopyable&); // ...but prevent copying
Uncopyable& operator=(const Uncopyable&);
};

To keep HomeForSale objects from being copied, all we have to do now is
inherit from Uncopyable:

class HomeForSale: private Uncopyable { // class no longer
... //
declares copy ctor or
}; // copy
assign. operator

-------------------------------------------------------

I understand that the copy ctor and copy assignment of class
HomeForSale will be implicitly generated by the compiler if needed. In
the copy ctor of HomeForSale, first it will call the default ctor of
Uncopyable implicitly. As for copy assignment, it won't call the
counterpart in the base class.


But why the author says:

-------------------------------------------------------
This works, because compilers will try to generate a copy constructor
and a copy assignment operator if anybody - even a member or friend
function - tries to copy a HomeForSale object. As Item 12 explains,
the compiler-generated versions of these functions will try to call
their base class counterparts, and those calls will be rejected,
because the copying operations are private in the base class.
-------------------------------------------------------

I tried it in VC7.0 and it did come out with a compiled error instead
of a link error.

Thanks in advance!

Right. So what's your question? That it came out with compile error
instead of link error? That's what happens. I don't see anything in what
you quoted saying it would generate a link error. What are you asking?
 
S

Sylvester Hesp

campos said:
"Effective C++ 3rd Edition" Item 6, P39
-------------------------------------------------------
This works, because compilers will try to generate a copy constructor
and a copy assignment operator if anybody - even a member or friend
function - tries to copy a HomeForSale object. As Item 12 explains,
the compiler-generated versions of these functions will try to call
their base class counterparts, and those calls will be rejected,
because the copying operations are private in the base class.
-------------------------------------------------------

I tried it in VC7.0 and it did come out with a compiled error instead
of a link error.

Thanks in advance!

So? A compile error is just what you'd expect to get, right? The author says
nothing about link errors (you will get link errors when someone that's both
a friend of Base _and_ Derived (or is a member of one and a friend of the
other) tries to copy the object)

- Sylvester
 
C

campos

Thanks Sylvester,

What I am puzzled with is that the author says "the compiler-generated
versions of these functions will try to call their base class
counterparts, and those calls will be rejected,
because the copying operations are private in the base class."

I don't know why the counterparts in base class will be called.
 
S

Sylvester Hesp

The generated copy ctor of the derived class will call the copy ctor of it's
base. Which makes sense, the derived class is only responsible for copying
it's own members, and any copying that needs to be done inside the base
class is the responsibility for the base class itself. So in your example,
the compiler will implicitely generate the following function:

HomeForSale(const HomeForSale & other) : Uncopyable(other)
{
}

But the copy ctor of Uncopyable is inaccessible for HomeForSale members (as
it's private to Uncopyable and HomeForSale isn't a friend of Uncopyable), so
you'll get a compile error.

Exactly the same goes for assignment operators.

- Sylvester
 
C

campos

Oh, I see.

If I define a copy ctor explicitly in derived class without calling the
copy ctor of base class in initializer list, the compiler will call the
default ctor of base class implicitly.

But if I do not define the copy ctor in derived class, the compiler
will generate a copy ctor which will call the copy ctor of base class
at first.

That's the difference.


However, as for copy assignment, the compiler will implicitly generate
the following fuction:

HomeForSale& operator=(const HomeForSale& rhs)
{
Uncopyable::eek:perator=(rhs);
}

The calling of function in base class is where the compile error comes
from.
 
T

tolgaceylanus

Uncopyable can be fragile IMHO, if you happen to define a copy-cons,
and assignment
in the derived class by mistake, then uncopyable is pretty much ignored
since the custom
assignment and copy-cons do not call the base counterparts
automatically.

Probably this scenario would cause long hours debugging to figure out
what's going on...
You have some classes that inherit uncopyable, yet somewhere deep in
the code
some code is able to copy these...

Just something to keep in mind...

Tolga Ceylan
 
T

tolgaceylanus

campos said:
Oh, I see.

If I define a copy ctor explicitly in derived class without calling the
copy ctor of base class in initializer list, the compiler will call the
default ctor of base class implicitly.

Not correct. Custom copy-ctor will not call base counterpart
automatically.
The same goes for assignment, custom assignment operator will not
call the base counter part automatically.
But if I do not define the copy ctor in derived class, the compiler
will generate a copy ctor which will call the copy ctor of base class
at first.

Yes... Compiler generated copy-cons will call base counter part
automatically.
 
S

Sylvester Hesp

campos said:
Oh, I see.

If I define a copy ctor explicitly in derived class without calling the
copy ctor of base class in initializer list, the compiler will call the
default ctor of base class implicitly.

Ah right, I missed the part where you defined your own copy ctor in
HomeForSale. Well yes, if you omit the base copy ctor call in the
initialized list, the default ctor for Uncopyable will get called

- Sylvester
 
C

campos

Not correct. Custom copy-ctor will not call base counterpart
automatically.
The same goes for assignment, custom assignment operator will not
call the base counter part automatically.


Hey, I've tried it just now.

Defaul ctor will be called at the beginning if default copy ctor of
base class is not declared explicitly in initializer list. If the
default ctor of base class is unavailable, a compile error will occur.


Anyway, thanks all~
 
S

Sylvester Hesp

Not correct. Custom copy-ctor will not call base counterpart
automatically.
The same goes for assignment, custom assignment operator will not
call the base counter part automatically.

It will call the _default_ ctor if you don't specify a base ctor call in the
initializer list, which is what he was talking about :)

- Sylvester
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top