Initialising private base members in copy constructor

F

Fraser Ross

template<typename T,
typename CounterPolicy = SimpleReferenceCount,
typename ObjectPolicy = StandardObjectPolicy>
class CountingPtr : private CounterPolicy, private ObjectPolicy {
private:
// shortcuts:
typedef CounterPolicy CP;
typedef ObjectPolicy OP;

T* object_pointed_to;
public:

// copy constructor:
CountingPtr (CountingPtr<T,CP,OP> const& cp)
: CP((CP const&)cp), // copy policies
OP((OP const&)cp) {
this->attach(cp); // copy pointer and increment counter
}

I'm not sure why the casts work. Why wasn't static_cast used instead?
Since the inheritances are private I'm surprised that casts can be done.
Some compilers don't appear to even require a cast at all.

Fraser.
 
V

Victor Bazarov

Fraser said:
template<typename T,
typename CounterPolicy = SimpleReferenceCount,
typename ObjectPolicy = StandardObjectPolicy>
class CountingPtr : private CounterPolicy, private ObjectPolicy {
private:
// shortcuts:
typedef CounterPolicy CP;
typedef ObjectPolicy OP;

T* object_pointed_to;
public:

// copy constructor:
CountingPtr (CountingPtr<T,CP,OP> const& cp)
: CP((CP const&)cp), // copy policies
OP((OP const&)cp) {
this->attach(cp); // copy pointer and increment counter
}

I'm not sure why the casts work. Why wasn't static_cast used instead?

How are the copy constructors defined in the 'CounterPolicy' and the
'ObjectPolicy' classes used to instantiate this template? IOW, you did
not post enough code to answer your question.
Since the inheritances are private I'm surprised that casts can be
done. Some compilers don't appear to even require a cast at all.

V
 
F

Fraser Ross

"Victor Bazarov"
How are the copy constructors defined in the 'CounterPolicy' and the
'ObjectPolicy' classes used to instantiate this template? IOW, you did
not post enough code to answer your question.

They are usually small classes that don't define copy constructors.
There is enough code pasted.

The subject should have been "Initialising private base classes in copy
constructor".

Fraser.
 
V

Victor Bazarov

Fraser said:
"Victor Bazarov"

They are usually small classes that don't define copy constructors.

Ah. OK.
There is enough code pasted.

I am not going to argue based on a technicality.
The subject should have been "Initialising private base classes in
copy constructor".

The conversion works regardless of where it occurs. What you have is
essentially

class DerivedClass : public BaseClass1, public BaseClass2 {};

DerivedClass object;
DerivedClass const& rderived = object;
BaseClass1 const & rb1 = (BaseClass1 const &) rderived;
BaseClass2 const & rb2 = (BaseClass2 const &) rderived;

in which the casts before the 'derived' in the initialisation of 'rb1'
and 'rb2' are _absolutely_ unnecessary. The conversion should work
without them. Have you tried removing them at all?

V
 
J

James Kanze

template<typename T,
typename CounterPolicy = SimpleReferenceCount,
typename ObjectPolicy = StandardObjectPolicy>
class CountingPtr : private CounterPolicy, private ObjectPolicy {
private:
// shortcuts:
typedef CounterPolicy CP;
typedef ObjectPolicy OP;
T* object_pointed_to;
public:
// copy constructor:
CountingPtr (CountingPtr<T,CP,OP> const& cp)
: CP((CP const&)cp), // copy policies
OP((OP const&)cp) {
this->attach(cp); // copy pointer and increment counter
}
I'm not sure why the casts work. Why wasn't static_cast used
instead?

Because static_cast doesn't ignore the private. This is the one
thing that you can only do with a C style cast. Except that
here...
Since the inheritances are private I'm surprised that casts can be done.
Some compilers don't appear to even require a cast at all.

At this point, you're in the context of CountingPtr, so you have
access to the private bases. No cast is required, and IMHO,
it's very bad policy to use one. (If you have to, of course,
static_cast is to be preferred, but in general, the conversion
to base is one of the foundations of OO programming, to the
point of being an exception to the rule that implicit
conversions should be avoided.)

Outside of CountingPtr, of course, static_cast won't work, but a
C style cast will. (I don't know why the standard says this.
Some historical reason, probably.) In general, however, private
inheritance is (or should be) an implementation detail; outside
of the class, you should code as if it wasn't there.
 
J

James Kanze

Are pointers/references to derived objects convertible to
pointers/references of private base classes that are directly inherited
as it says in this article:http://msdn2.microsoft.com/en-us/library/5bw4yh4d(VS.80).aspx ?

I didn't read the article in detail, but it certainly started
out on the right foot. Access control is orthogonal to
conversions; the implicit conversion exists, regardless of the
type of heritage (private or public). Access control determines
whether you have a right to use it or not; if the heritage is
private, you only have a right to use the conversion within the
class itself.

C style casts ignore access control, so you can violate this
restriction at will. I can't think of a case where you'd want
to, however. (And I would never use a C style cast for a
pointer or reference conversion.)
 

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

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top