Override public virtual Functions with private Functions?

Discussion in 'C++' started by Chris Gordon-Smith, May 26, 2008.

  1. Hello All

    I have a base class called Action_Request, and a set of classes
    corresponding to different kinds of Action_Request, each of which inherits
    from Action_Request. Eg:-

    class Add_Molecule_Req: public Action_Request{
    // ......

    I manipulate the various derived classes polymorphically through
    Action_Requests's public interface, using its virtual functions.
    Currently the overriding functions in the derived classes (including the
    destructor, which overrides Action_Request's virtual destructor), are
    declared public.

    My program compiles if I make them private, and doing this would seem to
    have the advantage that these functions must then always be invoked
    polymorphically through Action_Request's public interface, which is what I

    My questions are:-

    i) Is overriding public virtual functions with private functions good
    ii) Are there any disadvantages?

    Chris Gordon-Smith
    Chris Gordon-Smith, May 26, 2008
    1. Advertisements

  2. Chris Gordon-Smith

    dizzy Guest

    In general you should separate interface (the public API the base class
    provides) from configurability (the overriding feature). This is also
    called the Template Method Pattern and is described in detail here:
    dizzy, May 26, 2008
    1. Advertisements

  3. Sounds sensible to me. What I hadn't appreciated (because I hadn't really
    thought about it), is that private methods in derived class can override
    public methods in the base.
    In my case that is not a problem, because manipulation should only ever take
    place through the base. If I ever attempt manipulation through a derived
    class pointer I will get a compiler error. Upcasting would be possible, but
    would be working against my basic design principle.

    Chris Gordon-Smith
    Chris Gordon-Smith, May 26, 2008
  4. Chris Gordon-Smith

    James Kanze Guest

    It's more a style issue than anything else. My personal
    guidelines are to never change the access of a virtual function
    in the derived class, since I find it confusing that the same
    function has different access depending on the static type used
    to access it. The disadvantage that I see is that someone
    working on the derived class, later, may think that the
    functions in question cannot be called from outside the class.
    And of course, making them private does sort of violate the LSP:
    if I have a Derived, I can't call them, although I could if I
    had a Base.
    James Kanze, May 27, 2008
  5. Chris Gordon-Smith

    anon Guest

    Interesting article. It says that in some cases the destructor should be
    made protected. I have never thought about it before, and it made me
    wonder why would anyone make the destructor private or protected.
    So, the question is what are uses of such destructor?
    anon, May 27, 2008
  6. Chris Gordon-Smith

    Barry Guest

    Considering a class wrapping only static function as helper or factory
    function, we should make the dtor private not to allow any instance.

    We can also make the dtor private and with a static function "destroy"
    to allow instance created only by new (no stack allocation)

    making the dtor protected, then child class publicly/protectedly
    derived from from still has access to it. at this time, you can never
    delete a pointer to the base class.
    Barry, May 27, 2008
  7. Chris Gordon-Smith

    James Kanze Guest

    If the destructor is protected or private, you cannot allocate
    static or automatic instances of the type, and you cannot call
    delete on pointers to the type. In client code; you can still
    do pretty much anything you want in the implementation of the
    class itself.

    Private destructors might make sense if the class itself
    controls its lifetime: the only time it should be destructed is
    in response to some external event (in which case, it does a
    delete this). This is often the case for entity classes, for

    Protected destructors make a lot of sense for classes which are
    designed to be used as base classes (and only as base classes),
    but which don't have a virtual destructor. Classes like
    std::iterator<>, for example.
    James Kanze, May 27, 2008
  8. Thanks for this - interesting. As I understand it, the Liskov Substitution
    Principle (LSP) is about maintaining the "is a" relationship between the
    derived class and the base class. What I am trying to do is to use the base
    class to provide a common interface to a set of classes that can be used
    polymorphically. Does the LSP apply in this case?

    Chris Gordon-Smith
    Chris Gordon-Smith, May 27, 2008
  9. I don't think I would call it an error, but it would not be how I intend the
    class to be used. The code that uses my class is now more complex, because
    sometimes it uses the base class interface directly, and sometimes uses it
    by up-casting.

    Chris Gordon-Smith
    Chris Gordon-Smith, May 27, 2008
  10. Chris Gordon-Smith

    Daniel T. Guest

    That latter comment is a strong reason to go ahead and make the member-
    function public in the derived class.
    Daniel T., May 27, 2008
  11. Not really. The fact that up-casting would be necessary is a strong
    indication that the class is not intended to be used in this way. By only
    using the base class interface we keep the calling code simple and avoid
    any up-casting.

    Chris Gordon-Smith
    Chris Gordon-Smith, May 27, 2008
  12. Chris Gordon-Smith

    Daniel Pitts Guest

    The real question is, why don't you want people to call
    Derived->baseMethod()? What harm comes from it, and what benefit comes
    from preventing it?

    Polymorphic methods work the same whether you have a pointer/reference
    to a Base or Derived class. That's *why* they are virtual.
    Daniel Pitts, May 27, 2008
  13. The benefit is standardisation and simplification. The base and its derived
    classes are designed to be used polymorphically in a standard way through
    the base class's interface. Using the interfaces of the various derived
    classes would go against this and increase overall complexity and introduce
    the possibility of error. If the classes are used in the way intended,
    there is no need to call using the derived class's interface.
    Chris Gordon-Smith
    Chris Gordon-Smith, May 28, 2008
  14. Chris Gordon-Smith

    James Kanze Guest

    It depends on how you consider the LSP. It most definitely
    violates the usual understanding of LSP. Typically, in C++,
    this violation won't be visible, since client code expecting a
    Base will take a Base* or a Base&, and won't see the fact that
    the functions are private in the derived class. It might become
    visible, however, in the presense of templates.
    James Kanze, May 28, 2008
  15. Chris Gordon-Smith

    James Kanze Guest

    One of the characteristics of inheritance is normally that the
    Base class' interface is part of the derived class' interface,
    i.e. if I have something like:

    struct Base { void f() ; } ;
    struct Derived : Base { void g() ; } ;

    then the "interface" defined by Derived includes both f() and
    James Kanze, May 28, 2008
  16. True enough. In the case of my Action_Requests however, I don't want to use
    the derived class' interface. I always want to call polymorphically through
    the base interface.

    Chris Gordon-Smith
    Chris Gordon-Smith, May 28, 2008
  17. Chris Gordon-Smith

    James Kanze Guest

    In that case, you probably also want a factory which returns the
    actual instances, so that the client code doesn't even know that
    the derived classes exist. (And of course, in that case,
    whether the virtual functions are public or are private in the
    derived class really doesn't matter, since the client code
    doesn't have access to the derived class definition.)
    James Kanze, May 28, 2008
  18. Yes. I have something like this. I make objects of the derived class
    by reading input from a file. Depending on the kind of 'request' in
    the file. I make an object of the appropriate derived class. Once this
    has been done, nothing in the client code that manipulates the objects
    knows about the derived classes.

    (Hope this posting gets through OK. I can't get onto my news server at
    the moment and so have had to go onto Google groups.)

    Chris Gordon-Smith
    Chris Gordon-Smith, May 29, 2008
  19. Chris Gordon-Smith

    Daniel Pitts Guest

    If you want to "hide" the implementation classes from client code, put
    them into a anonymous namespace. That way, they can't ever access the
    symbols that represent them, and they can only ever have access to your
    instance through base class pointers or references.
    Daniel Pitts, May 29, 2008
  20. Interesting. I just tried that, but now unfortunately my program won't link
    because my factory class can't see the derived class' constructor.

    Chris Gordon-Smith
    Chris Gordon-Smith, May 29, 2008
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.