By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,669 Members | 1,634 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,669 IT Pros & Developers. It's quick & easy.

Am I missing something in private inheritance?

P: n/a
May someone explain why does this compile?
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
// Whatever
};


int main()
{
SomeClass obj;
}
Since we have *private* virtual inheritance, the public constructor
HiddenSealBaseClass() should have become private after Sealed
derivation, and thus inaccessible to SomeClass.


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
"Ioannis Vranos" <iv*@remove.this.grad.com> wrote...
May someone explain why does this compile?
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
// Whatever
};


int main()
{
SomeClass obj;
}
Since we have *private* virtual inheritance, the public constructor
HiddenSealBaseClass() should have become private after Sealed derivation,
and thus inaccessible to SomeClass.


That's utter nonsense.

class A {
public:
void foo();
};

class B : A { // private inheritance
};

int main() {
A a;
a.foo(); // according to you it shouldn't compile because
// somebody else inherits from A privately
}

Victor
Jul 22 '05 #2

P: n/a
* Victor Bazarov:
"Ioannis Vranos" <iv*@remove.this.grad.com> wrote...
May someone explain why does this compile?
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
// Whatever
};


int main()
{
SomeClass obj;
}
Since we have *private* virtual inheritance, the public constructor
HiddenSealBaseClass() should have become private after Sealed derivation,
and thus inaccessible to SomeClass.


That's utter nonsense.

class A {
public:
void foo();
};

class B : A { // private inheritance
};

int main() {
A a;
a.foo(); // according to you it shouldn't compile because
// somebody else inherits from A privately
}


The problem is more subtle than that, Victor, in your example
somewhat analogous to

class C: public B
{
void victorLookHere(){ foo(); }
};

What might make the analogy break down is that this is about a
default constructor and virtual inheritance, not ordinary
inheritance and an ordinary member function or constructor.

The reason there is doubt is that at least three modern compilers
don't complain.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #3

P: n/a
Victor Bazarov wrote:
That's utter nonsense.

class A {
public:
void foo();
};

class B : A { // private inheritance
};

int main() {
A a;
a.foo(); // according to you it shouldn't compile because
// somebody else inherits from A privately
}



Nope. You are using two classes while I am using three. Making your
example more equivalent:

class A {
public:
void foo();
};

class B : A {
};
class C: B {};

int main() {
C a;
a.foo();
}
This does not compile.

or even more equivalent:

class A {
public:
void foo();
};

class B : virtual A {
};
class C: B {};

int main() {
C a;
a.foo();
}

The above does not compile too, however it does compile if we use a
public A() constructor.


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #4

P: n/a
Alf P. Steinbach wrote:
* Victor Bazarov:
"Ioannis Vranos" <iv*@remove.this.grad.com> wrote...
May someone explain why does this compile?
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
// Whatever
};


int main()
{
SomeClass obj;
}
Since we have *private* virtual inheritance, the public constructor
HiddenSealBaseClass() should have become private after Sealed derivation,
and thus inaccessible to SomeClass.
That's utter nonsense.

class A {
public:
void foo();
};

class B : A { // private inheritance
};

int main() {
A a;
a.foo(); // according to you it shouldn't compile because
// somebody else inherits from A privately
}

The problem is more subtle than that, Victor, in your example
somewhat analogous to

class C: public B
{
void victorLookHere(){ foo(); }


So, we're saying that in this case 'C' shouldn't know that it's derived
from 'A' (as well) since 'A' is a private base of 'B', right? IOW, to
anybody outside 'B' B::foo() does not exist, right? Actually I agree.

So, in 'C' scope, 'foo' shouldn't be resolved to A::foo because 'C' must
not know about 'A' being one of its base classes. Perfectly fine.
};

What might make the analogy break down is that this is about a
default constructor and virtual inheritance, not ordinary
inheritance and an ordinary member function or constructor.
Yes. The need to construct a virtual base class object in the most
derived class' constructor makes the whole thing tricky.

The reason there is doubt is that at least three modern compilers
don't complain.


So, Alf, what's your take on it? I say, since the default c-tor of the
virtual base class is public, it should be accessible. Do you think
otherwise? Could you give justification (from the Standard) why it would
not be accessible? While you're at it, look at 12.6.2/6. "If V does not
have an accessible default constructor, the initialisation is ill-formed".
IOW, if it does [have an accessible default constructor], it would be OK.

Thanks.

V
Jul 22 '05 #5

P: n/a
Ioannis Vranos wrote:
Victor Bazarov wrote:
That's utter nonsense.

class A {
public:
void foo();
};

class B : A { // private inheritance
};

int main() {
A a;
a.foo(); // according to you it shouldn't compile because
// somebody else inherits from A privately
}


Nope. You are using two classes while I am using three. Making your
example more equivalent:

class A {
public:
void foo();
};

class B : A {
};
class C: B {};

int main() {
C a;
a.foo();
}
This does not compile.


Of course it doesn't. You're treating 'foo' as if it's a member of 'C'.
Your original post required access to A::A(), which was never private to
begin with.
or even more equivalent:

class A {
public:
void foo();
};

class B : virtual A {
};
class C: B {};

int main() {
C a;
a.foo();
}

The above does not compile too, however it does compile if we use a
public A() constructor.


Again. C::foo is private. A::A is not.

Victor
Jul 22 '05 #6

P: n/a
* Victor Bazarov:

So, Alf, what's your take on it? I say, since the default c-tor of the
virtual base class is public, it should be accessible. Do you think
otherwise?
In part I do. I disagree strongly with the justification, it does not make
sense to me. Regarding the conclusion, for the specific case of default
constructor, I do not know.

Could you give justification (from the Standard) why it would
not be accessible?


Private inheritance.

It gives non-accessibility for anything except the generated default
constructor.

For the generated default constructor, I do not know, but as earlier
stated I strongly suspect a compiler bug in three compilers, namely Comeau, GNU
and MSVC.

For example, the following code does _not_ compile with MSVC, which is as it
should be IMHO:
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
SomeClass(): HiddenSealBaseClass() {}
// Whatever
};

int main()
{
SomeClass obj;
}
vc_project.cpp(22): error C2248: 'SomeClass::SomeClass' : cannot access private
member declared in class 'SomeClass'

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #7

P: n/a
"Alf P. Steinbach" <al***@start.no> wrote...
* Victor Bazarov:

So, Alf, what's your take on it? I say, since the default c-tor of the
virtual base class is public, it should be accessible. Do you think
otherwise?


In part I do. I disagree strongly with the justification, it does not
make
sense to me. Regarding the conclusion, for the specific case of default
constructor, I do not know.

Could you give justification (from the Standard) why it would
not be accessible?


Private inheritance.

It gives non-accessibility for anything except the generated default
constructor.

For the generated default constructor, I do not know, but as earlier
stated I strongly suspect a compiler bug in three compilers, namely
Comeau, GNU
and MSVC.

For example, the following code does _not_ compile with MSVC, which is as
it
should be IMHO:
class HiddenSealBaseClass
{
public:
HiddenSealBaseClass() { }
};

class Sealed: virtual HiddenSealBaseClass
{};

class SomeClass: Sealed
{
SomeClass(): HiddenSealBaseClass() {}
// Whatever
};

int main()
{
SomeClass obj;
}
vc_project.cpp(22): error C2248: 'SomeClass::SomeClass' : cannot access
private
member declared in class 'SomeClass'


This is where I am puzzled to the extreme. It seems that SomeClass has
less access to 'HiddenSealBaseClass' than anybody else. That goes against
_any_ possible role an access specifier is supposed to play.

Now, here is another example where it would be really bad.

I have two classes, B and D. B has a public default constructor (whether
it's generated or user-defined shouldn't matter). In D I have an object
of type B, which is created using all default ways (no mention of it in
the D's constructor initialiser list). Now, I decide to inherit [some
functionality] from a third-party class C, which at the time virtually and
publicly derived from B. My program is well-formed. Now, the third party
decides to change public inheritance to private. BAM! Suddenly, my
program's well-formedness depends on whether C is derived from B and how.
What?!! No, sorry, B's constructor is public and it should be accessible
_no_matter_ who and how intends to use it.

The main point of private inheritance is to prevent automatic conversions
from the derived to base. When the base class is used/instantiated without
any intervening derived members (and that's the case in virtual inheritance
among others), IOW, directly, the access used is the one that's specified
by the base class _itself_.

Victor
Jul 22 '05 #8

P: n/a
Victor Bazarov wrote:
or even more equivalent:

class A {
public:
void foo();
};

class B : virtual A {
};
class C: B {};

int main() {
C a;
a.foo();
}

The above does not compile too, however it does compile if we use a
public A() constructor.

Again. C::foo is private. A::A is not.

Yes, however, why this does not happen in the case of a public default
constructor?

It looks like the type of inheritance (private, protected, public), does
not affect inherited public/protected constructors, but only inherited
public/protected data members and member functions.

Is this right?


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #9

P: n/a
"Ioannis Vranos" <iv*@remove.this.grad.com> wrote...
[..]
It looks like the type of inheritance (private, protected, public), does
not affect inherited public/protected constructors, but only inherited
public/protected data members and member functions.

Is this right?


Constructors are not inherited, perhaps that's the explanation you're
looking for.

Victor
Jul 22 '05 #10

P: n/a
Victor Bazarov wrote:
Constructors are not inherited, perhaps that's the explanation you're
looking for.

Yes, that's it I guess.
However (*this is another case*) strangely enough, this code from the
FAQ works:
class Fred;

class FredBase {
private:
friend class Fred;
FredBase() { }
};

class Fred : private virtual FredBase {
public:
...
};

That is, although FredBase() constructor is *private*, Fred being a
friend of FredBase "has access" to this constructor.
So in summary, constructors are not inherited, however a class being a
friend can access private constructors as happens with usual private
methods.


--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.