Thread: overide member function with calling base virtual function

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    159

    overide member function with calling base virtual function

    Hi,
    I was trying to write two classes A and C derived from a base class B. There is a virtual member function f in base class B. The derived class A does not override and therefore uses the virtual member function f of the base class. For the other derived class C, it defined its own function f overriding the virtual member function in the base class B.

    My question is: can I call B::f inside C::f? How can I do that? In C::f(), (B*)this->f() calls C::f() causing infinite times of invoking.

    Or other than that, is there any other mechanism that implements what I need?

    Thanks!

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Just call it directly:

    Code:
    class B : public C
    {
    	void f( void )
    	{
    		C::f();
    		// do stuff
    	}
    };
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    How can I do that? In C::f(), (B*)this->f() calls C::f() causing infinite times of invoking.
    This doesn't make sense. I don't think your base class function B::f() is calling the derived class's C::f(). There are tricks you can do in order to make this happen, but I doubt you are implementing any of those tricks.

    If you just have a regular virtual function, then the derived class's function will get called. If you want that derived function to call the base class function, then do what Sebastiani has implemented in the previous post.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by bithub View Post
    This doesn't make sense. I don't think your base class function B::f() is calling the derived class's C::f(). There are tricks you can do in order to make this happen, but I doubt you are implementing any of those tricks.
    In makes absolute sense.
    Since the function is C::f, calling C::f() will call just that - resulting in infinite loops.
    (B*)this->f() will not work either since the (B*) cast will cast the return of this->f()! And this->f() is the same as C::f().
    On the other hand, B::f() will work fine, just as ((B*)this)->f() will.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    37
    Quote Originally Posted by Elysia View Post
    In makes absolute sense.
    Since the function is C::f, calling C::f() will call just that - resulting in infinite loops.
    (B*)this->f() will not work either since the (B*) cast will cast the return of this->f()! And this->f() is the same as C::f().
    On the other hand, B::f() will work fine, just as ((B*)this)->f() will.
    I think the OP had two problems; the first being the order of operation error wich you fixed but even so I don't think ((B*) this)->f() will do what he wants since it will still call the virtual wich is again C::f(). B::f() however will work fine as you said since B::f() specifies a specific function that does not go through the virtual mechenism.

    Also I think maybe Sebastiani got it backwards. I think what he meant was this:

    Code:
    class C : public B
    {
    	virtual void f( )
    	{
    		B::f();
    		// do stuff
    	}
    };

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by SyntaxError View Post
    I think the OP had two problems; the first being the order of operation error wich you fixed but even so I don't think ((B*) this)->f() will do what he wants since it will still call the virtual wich is again C::f().
    Yes, you may be right on that one since it might just invoke a virtual function call again... My bad.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    159
    Thanks guys!
    Can you explain when to use "this->" and when to use "class::" inside the implementation of the class? Are these two equivalent for calling nonstatic class member?

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you use "this->function()", it's exactly the same thing as just saying "function()" (assuming you don't have any other symbols called "function"). It calls the function from the derived class's point of view. So if the derived class has defined the function, it will use that. Otherwise it will use a base class implementation, if there is one (inheritance in action).

    If you use "Class::", you're telling the compiler to use the function from a specific base class. (It's different from calling a static function.)

    [edit] I'm not sure another example is really necessary, but I wrote it, so I may as well post it.
    Code:
    #include <iostream>
    
    class Greeter {
    public:
        Greeter() {}
        
        virtual void greet() { std::cout << "Greetings.\n"; }
    };
    
    class FriendlyGreeter : public Greeter {
    public:
        virtual void greet() {
            std::cout << "Ah, my friend! ";
            Greeter::greet();
        }
    };
    
    int main() {
        FriendlyGreeter().greet();
        return 0;
    }
    [/edit]
    Last edited by dwks; 06-08-2009 at 02:30 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    37
    Quote Originally Posted by lehe View Post
    Thanks guys!
    Can you explain when to use "this->" and when to use "class::" inside the implementation of the class? Are these two equivalent for calling nonstatic class member?
    As dwks said this-> is optional. It's pretty much the same as not having it. However it catches your eye and makes it a bit easier to see you are calling a member function or using member data of the class. Some people like it, some people don't. The other thing is if you are programming in something like Visual studio, it will give you the pop-up list of members and data for the class, which is the chief reason I end up using it

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    As dwks said this-> is optional. It's pretty much the same as not having it.
    Well there are some instances where this-> is required (although they are rare). This usually comes into play when you have to differentiate between symbols that have the same name.

    Code:
    class Test
    {
        void foo() {}
        void bar(int foo) { this->foo(); } // Without this-> you will get a compile error
    };

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    That is a rather poor example, though. Normally you don't name your variables the same as your functions.
    But some practical scenarios I can think of is if you have a global function and a member function with the same name. Although, in this case, foo() still means this->foo(), so to call the global foo, you have to do ::foo().
    Template classes can also be tricky and demand that you use this->foo(), too. Those rules are tricky and I don't know them exactly 100% myself.

    Oh and @ dwks:
    Is that code really valid? It's true you can create a temporary object with your syntax, but a constructor doesn't return anything, so you can't call any member functions on it!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you're one of those people who like to do this . . .
    Code:
    void set_name(std::string name) { this->name = name; }
    Oh and @ dwks:
    Is that code really valid? It's true you can create a temporary object with your syntax, but a constructor doesn't return anything, so you can't call any member functions on it!
    Of course it's valid. You see, when you say Class(), you're creating a temporary object, on which you're welcome to call a method. If a function requires a Class variable as a parameter, you can create one with Class(...) on the spot. It's the same idea.

    Try it. :P

    [edit] I guess you could think of it this way: a constructor returns an instance of the class type being constructed , , , , I'm not sure if that's a technically valid description, but hey. [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    37
    Quote Originally Posted by bithub View Post
    Well there are some instances where this-> is required (although they are rare). This usually comes into play when you have to differentiate between symbols that have the same name.

    Code:
    class Test
    {
        void foo() {}
        void bar(int foo) { this->foo(); } // Without this-> you will get a compile error
    };
    Well yeah.... However I generally try to avoid doing silly things like this. It seems to me there is some semi-legitimate situation where you need this-> but it escapes me at the moment.

  14. #14
    Registered User
    Join Date
    May 2009
    Posts
    37
    Quote Originally Posted by dwks View Post
    If you're one of those people who like to do this . . .
    Of course it's valid. You see, when you say Class(), you're creating a temporary object, on which you're welcome to call a method. If a function requires a Class variable as a parameter, you can create one with Class(...) on the spot. It's the same idea.
    You sometimes use this in operator overloading. I was never quite sure where the object was created. I'm thinking almost for sure on the stack. However we used to call it magic space just to differentiate it from obvious stack objects.

    You have: global space, heap space, stack space and .... <gulp> .... magic space

  15. #15
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Definitely on the stack. Because it has to be freed automatically, and there's no easy way to make heap space automatically freed.

    IBM Linux Compilers
    [In C++,] temporary objects are unnamed objects created on the stack by the compiler. They are used during reference initialization and during evaluation of expressions including standard type conversions, argument passing, function returns, and evaluation of the throw expression.
    I like using this syntax when I'm creating an object just so that I can call one method on it. As long as it's readable, of course.

    P.S. Don't forget "executable space" for string literals. (Static space? Constant space?)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stroustrup Talk on C++0x
    By jverkoey in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 07-20-2007, 02:02 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Calling a member function from a different file
    By cdonlan in forum C++ Programming
    Replies: 3
    Last Post: 02-01-2005, 12:50 AM
  4. Calling a member function from a member function
    By Andystudent in forum C++ Programming
    Replies: 10
    Last Post: 05-15-2004, 01:04 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM