virtual inheritance question

I

Ioannis Vranos

Why this does not compile:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: virtual Sealed
{};

class Fred2: public Fred {};



int main()
{
Fred2 a;
}




while this compiles?:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: Sealed
{};

class Fred2: public Fred {};



int main()
{
Fred2 a;
}
 
V

Victor Bazarov

Ioannis Vranos said:
Why this does not compile:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: virtual Sealed
{};

class Fred2: public Fred {};

Vitual base class ('Sealed' in this case) is always constructed
in the initialisation list (or using a default c-tor) in the
_most_derived_ class ('Fred2' in this case). But here 'Fred2'
does not have access to 'Sealed's constructor.
int main()
{
Fred2 a;
}




while this compiles?:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: Sealed
{};

class Fred2: public Fred {};

Here, 'Fred2' constructs 'Fred' only, and 'Fred' constructs the
'Sealed' subobject. Since 'Fred' is a friend of 'Sealed', there
is no problem. Since 'Sealed' is not virtual, 'Fred2' doesn't
have anything to do with its construction.
int main()
{
Fred2 a;
}

V
 
B

Bob Hairgrove

Why this does not compile:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: virtual Sealed
{};

class Fred2: public Fred {};



int main()
{
Fred2 a;
}




while this compiles?:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: Sealed
{};

class Fred2: public Fred {};



int main()
{
Fred2 a;
}

I believe that with a virtual base class, its constructor must be
accessible to the most derived class; whereas with non-virtual base
classes, this is not the case.

However -- although I have a hard-copy of the C++ standard -- I was
NOT able to find the text to support this. I merely recall having seen
something on either this NG, or comp.std.c++, or the moderated version
of this NG which would support this assumption.

Apparently, assuming that my assumption stated above is true, the
friend declaration doesn't have an effect here. All I can say is that
I tried to compile the examples given here with the Comeau compiler,
and I got the same results as you did.
 
A

Alf P. Steinbach

* Ioannis Vranos:
Why this does not compile:


class Sealed
{
friend class Fred;
Sealed() { }
};

class Fred: virtual Sealed
{};

class Fred2: public Fred {};



int main()
{
Fred2 a;
}

With virtual inheritance the most derived class must call the
constructors of virtual base classes (in the most derived class'
constructor initialization list), and here the virtual base class
constructor is not available to the most derived class.

I think this is a FAQ.

At least it is a seldom used idiom to implement a sealed
(non-derivable) class, which the name 'Sealed' indicates.
 
I

Ioannis Vranos

Alf said:
With virtual inheritance the most derived class must call the
constructors of virtual base classes (in the most derived class'
constructor initialization list), and here the virtual base class
constructor is not available to the most derived class.

I think this is a FAQ.

At least it is a seldom used idiom to implement a sealed
(non-derivable) class, which the name 'Sealed' indicates.


Actually it came out of an attempt of mine to make an easily
implementable Sealed idiom, which was inspired from clc++ FAQ.

Since I understood this difference of behaviour, I will continue the
effort. :)
 
I

Ioannis Vranos

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 virtual inheritance, the public constructor
HiddenSealBaseClass() should have become private after Sealed
derivation, and thus inaccessible to SomeClass.
 
I

Ioannis Vranos

Ioannis said:
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 virtual private inheritance, the public constructor
 
A

Alf P. Steinbach

* Ioannis Vranos:
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.

I don't know whether I agree or not; this is tricky.

On the one hand, it shouldn't matter to a derived class whatever
private things a base class has: they're private, including private
virtual bases.

On the other hand, (1) if so then the idiom shouldn't work with private
virtual inheritance, and that's how it's presented in the FAQ, and (2) I
can't find anything in the standard that makes an exception to the rule
of most derived class call of the virtual base constructor, and (3)
simply by adding an argument (no _default_ constructor) both MSVC and
g++ report that the constructor is unavailable.

So in sum I think I lean strongly towards "compiler bug".

But then it's a bug in at least three different modern compilers (Comeau
4.3.3, MingW g++ 3.4.2, and MSVC 7.1) -- so perhaps it's not... ;-)
 
I

Ioannis Vranos

Alf said:
So in sum I think I lean strongly towards "compiler bug".

But then it's a bug in at least three different modern compilers (Comeau
4.3.3, MingW g++ 3.4.2, and MSVC 7.1) -- so perhaps it's not... ;-)


:)
 

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
474,197
Messages
2,571,040
Members
47,634
Latest member
RonnyBoelk

Latest Threads

Top