private virtual functions and pure virtual functions with bodies

Discussion in 'C++' started by John Goche, Dec 4, 2006.

  1. John Goche

    John Goche Guest

    Hello,

    page 202 of Symbian OS Explained by Jo Stichbury states

    "All virtual functions, public, protected or private, should be
    exported"

    then page 203 states

    "In the rare cases where a pure virtual function body
    has a function body, it must be exported."

    ------------------------------

    I assume that if a derived class B implements a function f
    declared private and virtual in a base class A then upon
    invoking B::f an invocation of A::f will take place despite
    the fact that f is private in A. Also, is it possible to
    change the access specifier (e.g. from private to
    protected or public in this case?).

    Also, I have never seen a pure virtual function with a
    body. What does this mean? I thought that whenever
    a function is pure virtual it must end with a = 0 and
    contain no implementation. (?)

    Feedback appreciated,

    Thanks,

    JG
    John Goche, Dec 4, 2006
    #1
    1. Advertising

  2. John Goche

    Salt_Peter Guest

    John Goche wrote:
    > Hello,
    >
    > page 202 of Symbian OS Explained by Jo Stichbury states
    >
    > "All virtual functions, public, protected or private, should be
    > exported"
    >
    > then page 203 states
    >
    > "In the rare cases where a pure virtual function body
    > has a function body, it must be exported."
    >
    > ------------------------------
    >
    > I assume that if a derived class B implements a function f
    > declared private and virtual in a base class A then upon
    > invoking B::f an invocation of A::f will take place despite
    > the fact that f is private in A.


    No it won't, if A::f is private, it's private for all including for the
    B derivative.
    And even if A::f is public, calling B::f doesn't invoke A::f.

    > Also, is it possible to
    > change the access specifier (e.g. from private to
    > protected or public in this case?).


    What?

    >
    > Also, I have never seen a pure virtual function with a
    > body. What does this mean? I thought that whenever
    > a function is pure virtual it must end with a = 0 and
    > contain no implementation. (?)


    nope. The class is abstract. That does not prevent you from
    implementing the pure-virtual if you choose to. A nice feature to have.

    >
    > Feedback appreciated,
    >


    Nothing prevents you from calling a pure virtual function, unlike other
    languages.

    #include <iostream>

    class Base
    {
    public:
    virtual ~Base() = 0;
    virtual void foo() const = 0;
    };

    Base::~Base() { std::cout << "~Base()\n"; }
    void Base::foo() const { std::cout << "Base::foo()\n"; }

    class Derived : public Base
    {
    public:
    Derived() { }
    ~Derived() { std::cout << "~Derived()\n"; }
    void foo() const
    {
    std::cout << "Derived::foo()\n";
    Base::foo();
    }
    };

    int main()
    {
    Derived derived;
    derived.foo();
    }

    /*
    Derived::foo()
    Base::foo()
    ~Derived()
    ~Base()
    */
    Salt_Peter, Dec 4, 2006
    #2
    1. Advertising

  3. John Goche

    Guest

    On Dec 4, 12:57 pm, "John Goche" <> wrote:
    > Hello,
    >
    > page 202 of Symbian OS Explained by Jo Stichbury states
    >
    > "All virtual functions, public, protected or private, should be
    > exported"
    >
    > then page 203 states
    >
    > "In the rare cases where a pure virtual function body
    > has a function body, it must be exported."
    >
    > ------------------------------
    >
    > I assume that if a derived class B implements a function f
    > declared private and virtual in a base class A then upon
    > invoking B::f an invocation of A::f will take place despite
    > the fact that f is private in A.


    No, a private function can not be accessed from the derived class.

    > Also, is it possible to
    > change the access specifier (e.g. from private to
    > protected or public in this case?).


    Yes, you can declare a function public if it was private or protected
    in the base-class.

    > Also, I have never seen a pure virtual function with a
    > body. What does this mean? I thought that whenever
    > a function is pure virtual it must end with a = 0 and
    > contain no implementation. (?)


    Consider this:

    class Base {
    virtual int foo() = 0;
    public:
    virtual int bar();
    }

    int Base::foo() { return 1; }

    int Base::bar() return foo(); }

    class Derived : public Base {
    virtual int foo();
    public:
    virtual int bar();
    }

    int Derived::bar() { return A::bar(); }

    int Derived::foo() { return 0; }

    int main() {
    B b;
    std::cout << b.bar(); // will print 1
    }

    This allows you to use a private pure function with a body, however
    note that you must also provide a foo()-function in Derived, since it's
    a pure virtual function in Base.

    The use of private pure functions with bodies are perhaps not so great.
    Public pure functions with bodies can be very useful in providing part
    of the functionality wanted from the function, and still requireing any
    derived classes to provide their own implementation, even if it's just
    a Base::foo()-call.

    --
    Erik Wikström
    , Dec 4, 2006
    #3
  4. John Goche

    John Goche Guest

    Thank you Erik and Peter for the clarifications,

    The example really shows how a pure virtual function
    must be implemented in a derived class and prevents
    the base class from being instantiated directly but
    that an implementation of the pure virtual function
    in the base class may still exist and be accessed
    from some other function in the same base class
    or using an access specifier from a derived class
    for example.

    What is not clear to me though, is, if a private
    function cannot be called from a derived class,
    then what is the point of making such a
    function virtual???

    Thanks,

    JG

    wrote:
    > On Dec 4, 12:57 pm, "John Goche" <> wrote:
    > > Hello,
    > >
    > > page 202 of Symbian OS Explained by Jo Stichbury states
    > >
    > > "All virtual functions, public, protected or private, should be
    > > exported"
    > >
    > > then page 203 states
    > >
    > > "In the rare cases where a pure virtual function body
    > > has a function body, it must be exported."
    > >
    > > ------------------------------
    > >
    > > I assume that if a derived class B implements a function f
    > > declared private and virtual in a base class A then upon
    > > invoking B::f an invocation of A::f will take place despite
    > > the fact that f is private in A.

    >
    > No, a private function can not be accessed from the derived class.
    >
    > > Also, is it possible to
    > > change the access specifier (e.g. from private to
    > > protected or public in this case?).

    >
    > Yes, you can declare a function public if it was private or protected
    > in the base-class.
    >
    > > Also, I have never seen a pure virtual function with a
    > > body. What does this mean? I thought that whenever
    > > a function is pure virtual it must end with a = 0 and
    > > contain no implementation. (?)

    >
    > Consider this:
    >
    > class Base {
    > virtual int foo() = 0;
    > public:
    > virtual int bar();
    > }
    >
    > int Base::foo() { return 1; }
    >
    > int Base::bar() return foo(); }
    >
    > class Derived : public Base {
    > virtual int foo();
    > public:
    > virtual int bar();
    > }
    >
    > int Derived::bar() { return A::bar(); }
    >
    > int Derived::foo() { return 0; }
    >
    > int main() {
    > B b;
    > std::cout << b.bar(); // will print 1
    > }
    >
    > This allows you to use a private pure function with a body, however
    > note that you must also provide a foo()-function in Derived, since it's
    > a pure virtual function in Base.
    >
    > The use of private pure functions with bodies are perhaps not so great.
    > Public pure functions with bodies can be very useful in providing part
    > of the functionality wanted from the function, and still requireing any
    > derived classes to provide their own implementation, even if it's just
    > a Base::foo()-call.
    >
    > --
    > Erik Wikström
    John Goche, Dec 6, 2006
    #4
  5. John Goche

    Craig Scott Guest

    > What is not clear to me though, is, if a private
    > function cannot be called from a derived class,
    > then what is the point of making such a
    > function virtual???


    It is a common pattern for a public function in a base class to call a
    private virtual function(s). The public base function defines *what*
    steps to perform but the private virtual functions define *how* each
    step is implemented. The base function is more or less just the shell
    of the task and the subclass can override the private virtual functions
    as required to customize how each step is performed. This is the
    "Template Method" as explained in "Design Patterns" book by Gamma, et.
    al. I highly recommended you get your hands on a copy (as do most
    seasoned developers these days it seems!).

    --
    Computational Fluid Dynamics, CSIRO (CMIS)
    Melbourne, Australia
    Craig Scott, Dec 6, 2006
    #5
  6. John Goche

    Salt_Peter Guest

    [ Please don't Top Post - rearranged ]

    >
    > wrote:
    > > On Dec 4, 12:57 pm, "John Goche" <> wrote:
    > > > Hello,
    > > >
    > > > page 202 of Symbian OS Explained by Jo Stichbury states
    > > >
    > > > "All virtual functions, public, protected or private, should be
    > > > exported"
    > > >
    > > > then page 203 states
    > > >
    > > > "In the rare cases where a pure virtual function body
    > > > has a function body, it must be exported."
    > > >
    > > > ------------------------------
    > > >
    > > > I assume that if a derived class B implements a function f
    > > > declared private and virtual in a base class A then upon
    > > > invoking B::f an invocation of A::f will take place despite
    > > > the fact that f is private in A.

    > >
    > > No, a private function can not be accessed from the derived class.
    > >
    > > > Also, is it possible to
    > > > change the access specifier (e.g. from private to
    > > > protected or public in this case?).

    > >
    > > Yes, you can declare a function public if it was private or protected
    > > in the base-class.
    > >
    > > > Also, I have never seen a pure virtual function with a
    > > > body. What does this mean? I thought that whenever
    > > > a function is pure virtual it must end with a = 0 and
    > > > contain no implementation. (?)

    > >
    > > Consider this:
    > >
    > > class Base {
    > > virtual int foo() = 0;
    > > public:
    > > virtual int bar();
    > > }
    > >
    > > int Base::foo() { return 1; }
    > >
    > > int Base::bar() return foo(); }
    > >
    > > class Derived : public Base {
    > > virtual int foo();
    > > public:
    > > virtual int bar();
    > > }
    > >
    > > int Derived::bar() { return A::bar(); }
    > >
    > > int Derived::foo() { return 0; }
    > >
    > > int main() {
    > > B b;
    > > std::cout << b.bar(); // will print 1
    > > }
    > >
    > > This allows you to use a private pure function with a body, however
    > > note that you must also provide a foo()-function in Derived, since it's
    > > a pure virtual function in Base.
    > >
    > > The use of private pure functions with bodies are perhaps not so great.
    > > Public pure functions with bodies can be very useful in providing part
    > > of the functionality wanted from the function, and still requireing any
    > > derived classes to provide their own implementation, even if it's just
    > > a Base::foo()-call.
    > >
    > > --
    > > Erik Wikström


    John Goche wrote:
    > Thank you Erik and Peter for the clarifications,
    >
    > The example really shows how a pure virtual function
    > must be implemented in a derived class and prevents
    > the base class from being instantiated directly but
    > that an implementation of the pure virtual function
    > in the base class may still exist and be accessed
    > from some other function in the same base class
    > or using an access specifier from a derived class
    > for example.
    >
    > What is not clear to me though, is, if a private
    > function cannot be called from a derived class,
    > then what is the point of making such a
    > function virtual???
    >


    A creator programmer is writing a "rule" for the user of the class(es)
    that states that a pure-virtual function *must* be implemented in order
    to satisfy the requirements - thats the logic. Imagine a system that
    handles elements having the requirement that some given method() be
    available. Declaring the void method() as pure-virtual essentially
    guarentees that the derivatives will have that void method()
    implemented somewhere with the option of overriding it. Note: a derived
    class doesn't have to override that function *if* its already
    implemented lower in the inheritance hierarchy.

    Personally, i think that making a pure-virtual private is a bad idea.
    Also, suggesting that an abstract class should never have members is a
    ludicrous requirement ( such members in fact would ultimately become
    part of a derived entities anyways ). An interface in Java is not
    allowed to have members, but no such restriction is imposed on C++.
    And, IMHO, i don't see why such a restriction should be imposed.

    If a given set of composition members is common to an inheritance
    hierarchy, putting them elsewhere than in an abstract class is poor
    code. Even for a pure interface. I find that imposing such a rule
    outright is counter-productive. Except, of course, in the case where a
    particular language requires it. In the case you put forth, that sounds
    like a requirement made to satisfy an IDL compiler.
    Salt_Peter, Dec 7, 2006
    #6
  7. John Goche

    John Goche Guest

    Just as a note...
    Here is an example of how a derived class can
    invoke a private function in a base class when
    such function is declared virtual:

    #include <iostream>

    class A {
    private:
    virtual void foo() = 0;
    };

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

    void B::foo() {
    std::cout << "foo" << std::endl;
    }

    int main() {
    B b;
    b.foo();
    }

    output: foo
    John Goche, Dec 7, 2006
    #7
  8. John Goche

    Salt_Peter Guest

    John Goche wrote:
    > Just as a note...
    > Here is an example of how a derived class can
    > invoke a private function in a base class when
    > such function is declared virtual:
    >
    > #include <iostream>
    >
    > class A {
    > private:
    > virtual void foo() = 0;
    > };
    >
    > class B: public A {
    > public:
    > virtual void foo();
    > };
    >
    > void B::foo() {
    > std::cout << "foo" << std::endl;
    > }
    >
    > int main() {
    > B b;
    > b.foo();
    > }
    >
    > output: foo


    I hate to have to disappoint you, but thats not correct. The output
    comes from B::foo() (realize also that A::foo() is not even
    implemented). By the way: B::foo() is already virtual.
    Compile and run the following, read the output, then uncomment the call
    to A::foo(). Read the error.
    Note: base functions are *overriden* by virtual derived functions:
    --- the derived foo() *hides* the base's foo() ---
    so you must call it explicitly - and thats by design.

    #include <iostream>
    #include <ostream>

    class A {
    private:
    virtual void foo() const = 0;
    };

    void A::foo() const {
    std::cout << "A::foo()\n";
    }

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

    void B::foo() const {
    // A::foo(); // must be public in class A
    std::cout << "B::foo()\n";
    }

    int main() {
    B b;
    b.foo();
    }

    /*
    B::foo()
    */

    Finally, consider what happens if you derive from class B like this:

    class C : public B
    {
    };

    int main()
    {
    C c;
    c.foo(); // this works !!!
    }

    Do you understand now If you don't overide foo() what happens?
    Class A does not require all/each of its derivatives to implement
    foo(), as long as foo() is indeed implemented somewhere down the
    hierarchy, its indeed callable.
    Salt_Peter, Dec 7, 2006
    #8
  9. John Goche

    Marcus Kwok Guest

    Salt_Peter <> wrote:
    > Personally, i think that making a pure-virtual private is a bad idea.


    Guru Sutter disagrees with you:

    "When should virtual functions be public, protected, or private?"

    The short answer is: Rarely if ever, sometimes, and by default,
    respectively - the same answer we've already learned for other kinds
    of class members.

    http://www.gotw.ca/publications/mill18.htm

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
    Marcus Kwok, Dec 7, 2006
    #9
  10. John Goche

    Salt_Peter Guest

    Marcus Kwok wrote:
    > Salt_Peter <> wrote:
    > > Personally, i think that making a pure-virtual private is a bad idea.

    >
    > Guru Sutter disagrees with you:
    >
    > "When should virtual functions be public, protected, or private?"
    >
    > The short answer is: Rarely if ever, sometimes, and by default,
    > respectively - the same answer we've already learned for other kinds
    > of class members.
    >
    > http://www.gotw.ca/publications/mill18.htm
    >


    I'm already aware of the above. And my response is that if anything
    classifies a virtual function as one that should be private or
    protected, that *anything* shouldn't be placed in the virtual function
    at all. Place private parts in private member functions instead.
    Needless to say, that can't always lead to a viable solution.
    Salt_Peter, Dec 8, 2006
    #10
  11. John Goche

    Marcus Kwok Guest

    Salt_Peter <> wrote:
    > Marcus Kwok wrote:
    >> Salt_Peter <> wrote:
    >> > Personally, i think that making a pure-virtual private is a bad idea.

    >>
    >> Guru Sutter disagrees with you:
    >>
    >> "When should virtual functions be public, protected, or private?"
    >>
    >> The short answer is: Rarely if ever, sometimes, and by default,
    >> respectively - the same answer we've already learned for other kinds
    >> of class members.
    >>
    >> http://www.gotw.ca/publications/mill18.htm

    >
    > I'm already aware of the above. And my response is that if anything
    > classifies a virtual function as one that should be private or
    > protected, that *anything* shouldn't be placed in the virtual function
    > at all. Place private parts in private member functions instead.


    I'm sorry, I'm having a little trouble parsing the above...

    The article is saying that by default the virtual should be private, and
    should only be made public if there is a compelling reason to do so, and
    have a public non-virtual call the private virtual. This way, the
    interface (non-virtual function) is separated from the implementation
    (virtual function). If you have a public virtual, then it is specifying
    both.

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
    Marcus Kwok, Dec 8, 2006
    #11
    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. Ian Murphy

    Missing message bodies in newsgroup

    Ian Murphy, Mar 2, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    321
    Ian Murphy
    Mar 2, 2004
  2. qazmlp
    Replies:
    19
    Views:
    777
    Daniel T.
    Feb 4, 2004
  3. Todd Aspeotis
    Replies:
    3
    Views:
    451
    Kanenas
    May 30, 2005
  4. James

    Reading Email Bodies

    James, Nov 6, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    326
    James
    Nov 6, 2006
  5. Martin Vorbrodt

    private pure virtual function

    Martin Vorbrodt, Nov 1, 2005, in forum: C++
    Replies:
    10
    Views:
    553
    Kaz Kylheku
    Nov 2, 2005
Loading...

Share This Page