Private Virtual inheritance problem.

Discussion in 'C++' started by Elad, Mar 6, 2006.

  1. Elad

    Elad Guest

    Hello All,

    Im taking an OOP course, in one of the tutorials, there was a frozen
    class example, i.e. a class which is impossible to inherit from, the
    example was something like:

    struct ice__ {
    ice() {};
    };

    class Frozen : private virtual ice__ {
    Frozen () {}; // Will call ice__'s default c'tor, which is OK.
    };

    class Violation : public Frozen {
    Violation () {}; // Must call ice__'s c'tor which is impossible.
    };

    As I understand, since Frozen virtually inherits ice__, Violation which
    inherits Frozen must call ice's c'tor, which is impossible, as ice's
    c'tor is in the private part of Frozen.

    nevertheless, this example compiles and executes just fine under g++
    with ansi / pedantic flags. cl (MS's compiler) eats this as well.

    any clue ?


    Thanks,
    Elad.
     
    Elad, Mar 6, 2006
    #1
    1. Advertising

  2. Elad

    Jaspreet Guest

    Elad wrote:
    > Hello All,
    >
    > Im taking an OOP course, in one of the tutorials, there was a frozen
    > class example, i.e. a class which is impossible to inherit from, the
    > example was something like:
    >
    > struct ice__ {
    > ice() {};
    > };
    >
    > class Frozen : private virtual ice__ {
    > Frozen () {}; // Will call ice__'s default c'tor, which is OK.
    > };
    >
    > class Violation : public Frozen {
    > Violation () {}; // Must call ice__'s c'tor which is impossible.
    > };
    >
    > As I understand, since Frozen virtually inherits ice__, Violation which
    > inherits Frozen must call ice's c'tor, which is impossible, as ice's
    > c'tor is in the private part of Frozen.
    >
    > nevertheless, this example compiles and executes just fine under g++
    > with ansi / pedantic flags. cl (MS's compiler) eats this as well.
    >
    > any clue ?
    >
    >
    > Thanks,
    > Elad.


    In structures the default access specifier is public while in classes
    default specifier is private.

    So, Frozen would compile properly since its calling the default
    constructor of ice which is in public section. Now Violation would
    automatically call default constructor of Frozen which would be an
    error since Frozen's default constructor is in private scope.

    So you have just made Frozen as a non-derivable class. I however like
    the other step as mentioned in the FAQs to make a class final by
    specifying a comment on top of Frozen saying that this class should be
    final.
     
    Jaspreet, Mar 6, 2006
    #2
    1. Advertising

  3. Elad

    Sunil Varma Guest

    Elad wrote:
    > Hello All,
    >
    > Im taking an OOP course, in one of the tutorials, there was a frozen
    > class example, i.e. a class which is impossible to inherit from, the
    > example was something like:
    >
    > struct ice__ {
    > ice() {};
    > };
    >
    > class Frozen : private virtual ice__ {
    > Frozen () {}; // Will call ice__'s default c'tor, which is OK.
    > };
    >
    > class Violation : public Frozen {
    > Violation () {}; // Must call ice__'s c'tor which is impossible.
    > };
    >
    > As I understand, since Frozen virtually inherits ice__, Violation which
    > inherits Frozen must call ice's c'tor, which is impossible, as ice's
    > c'tor is in the private part of Frozen.
    >
    > nevertheless, this example compiles and executes just fine under g++
    > with ansi / pedantic flags. cl (MS's compiler) eats this as well.
    >
    > any clue ?
    >
    >
    > Thanks,
    > Elad.


    May i know the version of the g++ compiler you are using.
    i tried it on gcc 3.2.2, borland 5.5.1 and MS C++ compiler , i got
    compilation error in all the cases.
     
    Sunil Varma, Mar 6, 2006
    #3
  4. Elad

    benben Guest

    > struct ice__ {
    > ice() {};
    > };
    >
    > class Frozen : private virtual ice__ {
    > Frozen () {}; // Will call ice__'s default c'tor, which is OK.
    > };
    >
    > class Violation : public Frozen {
    > Violation () {}; // Must call ice__'s c'tor which is impossible.
    > };


    The above code actually rendered class Frozen TOTALLY unusable, not only
    underivable. In fact, unless you haven't copy the exact code here the
    compiler must issue you more than one errors, for example the typo of
    ice replacing a supposed ice__ and Violation::Violation's call to the
    private Frozen::Frozen.

    Perhaps you really meant the following:

    struct ice__ {
    ice__() {};
    };

    class Frozen : private virtual ice__ {
    public: // Frozen is usable
    Frozen () {};
    };

    class Violation : public Frozen {};

    Now the most derived class is supposed to make a call to the virtual
    base class's constructor. The reason why the compiler doesn't complain
    now is that up to this point the compiler has not a single clue whether
    class Violation is going to be the most derived class of any object,
    because not a single object is created yet.

    To ask for an error you need to make an object of Violation. For example:

    int main(){
    Frozen f; // Ok
    Violation v; // Error
    }

    Hope this will help.

    Regards,
    Ben
     
    benben, Mar 6, 2006
    #4
  5. Elad

    Elad Guest

    Hello Again,

    They was indeed a mistake in the code I gave (class'es ctor's were
    declared private), was in a rush, sorry about that.

    Ben, The code you suggested Is exactly what I ment, yet, for some
    reason it *does* compile :-(

    here is a copy paste of my test-code:

    #include <iostream.h>

    struct ice__ {
    ice__ () {
    cout << "ice__" << endl;
    };
    };

    class Frozen: private virtual ice__ {
    public:
    Frozen (void) {cout << "FROZEN" << endl;}
    };

    class Violation : public Frozen {
    public:
    Violation (void) { cout << "violation ?" << endl;}
    };


    int main(){

    Violation x;

    return 0;

    };

    This is the output of the executable:
    ice__
    FROZEN
    violation ?


    As I understand it should not compile what-so-ever ..
    It was compiled using g++ 3.4.4 with no problems.

    and with .NET's cl ..

    Help.
     
    Elad, Mar 6, 2006
    #5
  6. Elad

    Dervish Guest

    Everything is OK with your code. You can think about it in following
    way:
    1. ice__ has public ctor - everything OK.
    2. Frozen has public ctor and has access to ice ctor & therefore can
    call it - everything OK.
    3. Violation has public ctor and has access to Frozen public ctor -
    everything OK.
    So it is Frozen business how it is going to call ctors of basic
    classes. Essentially Valuation can't directly call any methods of
    ice__.
     
    Dervish, Mar 6, 2006
    #6
  7. Elad

    Elad Guest

    All is good but 3 :)

    When a base class is inherited virtualy, it is up to the *most derived*
    class to initialize it.

    It comes from multiple inheritance where virtual base classes are
    "united" hence none of the classes in the inheritance tree will call
    the virtual base's ctor but the most derived one - in this case it is
    Violation's responsibitly to call ice__'s ctor.
     
    Elad, Mar 6, 2006
    #7
  8. Elad

    benben Guest

    Oops

    I think I'd just make ice::ice private and Frozen a friend of ice:

    class Frozen;

    class ice
    {
    private:
    ice(){}
    friend class Frozen;
    };

    class Frozen: private virtual ice{};
    class Violation: public Frozen{};


    Ben
     
    benben, Mar 6, 2006
    #8
  9. Elad

    Rolf Magnus Guest

    Elad wrote:

    > All is good but 3 :)
    >
    > When a base class is inherited virtualy, it is up to the *most derived*
    > class to initialize it.
    >
    > It comes from multiple inheritance where virtual base classes are
    > "united" hence none of the classes in the inheritance tree will call
    > the virtual base's ctor but the most derived one - in this case it is
    > Violation's responsibitly to call ice__'s ctor.


    Yes, and it does that. What you could do is make ice__'s constructor private
    and make Frozen a friend of it. Then Violation can't call it, not even
    implicitly, as it does now.
     
    Rolf Magnus, Mar 6, 2006
    #9
  10. Elad

    Fei Liu Guest

    Elad wrote:
    > All is good but 3 :)
    >
    > When a base class is inherited virtualy, it is up to the *most derived*
    > class to initialize it.
    >
    > It comes from multiple inheritance where virtual base classes are
    > "united" hence none of the classes in the inheritance tree will call
    > the virtual base's ctor but the most derived one - in this case it is
    > Violation's responsibitly to call ice__'s ctor.


    hmm, code compiles/runs fine here, gcc version 2.96 20000731 (Red Hat
    Linux 7.1 2.96-85)
     
    Fei Liu, Mar 6, 2006
    #10
  11. Elad

    Elad Guest

    Hello Rolf,

    I'm still trying to figure the difference between theory and practice
    :)
     
    Elad, Mar 8, 2006
    #11
  12. Elad

    Ben Pope Guest

    Elad wrote:
    > Hello Rolf,
    >
    > I'm still trying to figure the difference between theory and practice
    > :)


    In theory, practice and theory are the same. In practice, they are
    different.

    Ben Pope
    --
    I'm not just a number. To many, I'm known as a string...
     
    Ben Pope, Mar 8, 2006
    #12
  13. Elad

    Rolf Magnus Guest

    Ben Pope wrote:

    > Elad wrote:
    >> Hello Rolf,
    >>
    >> I'm still trying to figure the difference between theory and practice
    >> :)

    >
    > In theory, practice and theory are the same. In practice, they are
    > different.


    In Germany, we have a saying that you can read from many office walls. Dunno
    if it's known in English too, but it goes something like:

    If you know everything, and nothing works, that's theory.
    If everything works, and nobody knows why, that's practice.
    In this room, theory and practice are combined in a perfect way:
    Nothing works, and nobody knows why.
     
    Rolf Magnus, Mar 8, 2006
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. maxw_cc
    Replies:
    1
    Views:
    3,148
    Martijn van Steenbergen
    Dec 21, 2003
  2. qazmlp
    Replies:
    19
    Views:
    798
    Daniel T.
    Feb 4, 2004
  3. John Goche
    Replies:
    10
    Views:
    753
    Marcus Kwok
    Dec 8, 2006
  4. karthikbalaguru
    Replies:
    9
    Views:
    1,041
  5. puzzlecracker
    Replies:
    8
    Views:
    906
    werasm
    Sep 29, 2007
Loading...

Share This Page