Thread: issues with accessing parent member functions by typecasting this pointer

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    19

    issues with accessing parent member functions by typecasting this pointer

    First of all, these are the classes that I defined

    Code:
    class A
    {
    protected:
    	void print() { cout << "A" << endl; }
    };
    
    class B : public A
    {
    public:
    	void print() { static_cast<A*>(this)->print(); }
    };
    And in the main() function, I did the following

    Code:
    int main()
    {
    	B b;
    	b.print();
    
    	return 0;
    }
    But I get the following error - error C2248: 'A :: print' : cannot access protected member declared in class 'A'

    But if I make the protected print() function of the class A static as shown below, print() function prints fine.

    Code:
    class A
    {
    protected:
    	static void print() { cout << "A" << endl; }
    };
    Why does it work only when print() is declared static? I think it might have to do with the casting and all that, but I wasn't exactly sure. I would appreciate for any help. Thanks in advance.

  2. #2
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think it's because if you do it like that, it's basically the same as doing this:
    Code:
    A* a = new A;
    a->print();
    Although I'm not sure why the static version works.

    Use this instead of the ugly cast:
    Code:
    void print() { A::print(); }

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    In this particular case you don't need anything more than:

    Code:
    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    	void print() { cout << "A" << endl; }
    };
    
    class B : public A
    {
    };
    
    int main()
    {
    	B b;
    	b.print();
    	return 0;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by cpjust View Post
    Although I'm not sure why the static version works.
    I'm not entirely sure either, but I think it's because you don't actually need the class itself to access a static function, and you have inherited the class, so any protected parts of the original class is available to this class too.

    The next question is of course why B will do the same job in public as the protected function of A - why not just make A's function public in the first place like anon says? If you make it available, then you make it available - moving it from protected to public.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    IMO, this is one of the downsides of how you access static methods in most object oriented languages. This code would work as well:

    ((A*) 5003)->print();

    It doesn't matter what you put in place of the 5003. If you cast it to an A* and call a static method, its equivalent to A::print(); I think its rather unfortunate that you can even access static methods through an object... I mean it suggests that the method is somehow tied to the object, which it of course isn't as my example clearly shows.

    Also, in the opposite direction, I think its unfortunate that you can call a base class non-static method using A::method(); This suggests that the method is somehow tied to the class, and not the object.

    ARRRG.

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by arpsmack View Post
    IMO, this is one of the downsides of how you access static methods in most object oriented languages. This code would work as well:

    ((A*) 5003)->print();

    It doesn't matter what you put in place of the 5003. If you cast it to an A* and call a static method, its equivalent to A::print(); I think its rather unfortunate that you can even access static methods through an object... I mean it suggests that the method is somehow tied to the object, which it of course isn't as my example clearly shows.

    Also, in the opposite direction, I think its unfortunate that you can call a base class non-static method using A::method(); This suggests that the method is somehow tied to the class, and not the object.

    ARRRG.
    Well whether the function is static or not, there's still just one of them in memory. You don't get a new copy of the function when you create a new instance of a class. The only difference between them is that the non-static function gets passed a this pointer behind the scenes. So I don't see a problem with either syntax.

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Quote Originally Posted by cpjust View Post
    Well whether the function is static or not, there's still just one of them in memory. You don't get a new copy of the function when you create a new instance of a class. The only difference between them is that the non-static function gets passed a this pointer behind the scenes.
    I don't see how this relates to my argument at all, but I'm not shocked in the least that someone disagrees with me.

    It's not like I feel very strongly about this. It just bothers me a little that I can look at code like this:
    Code:
    int main(void) {
       A myA;
       myA.DoStuff();
    }
    and wouldn't be able to tell if DoStuff() is a class method or not, even though it could have been easily been written:
    Code:
    int main(void) {
       A::DoStuff();
    }
    with absolutely no doubt at all.

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I'm not sure why you'd need to know if the function is static or not, but I guess if you really want to know that (without looking at the header file) then you do have a point. A good IDE might be able to distinguish static vs non-static member functions for you, but I'm not aware of any that do that. (Maybe Eclipse?)

  9. #9
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Quote Originally Posted by cpjust
    I'm not sure why you'd need to know if the function is static or not
    Yeah I actually have no idea why I'd need to know. I spent a good couple minutes thinking about it, and I've got nothin'.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    I think the method definition in B is shadowing the method definition in A. When the one in A is static it's not shadowing because it's no longer like an overload of the same method.
    See what happens when you add a using statement. for A::print into B.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The OS I work on often use static functions in a class to allow for two-step construction [to make it more robust against out of memory situations].

    There are other situations where static functions are useful - for example for getting information that is not really part of the class itself, such as "supported configurations" (a list of pixelformats for example), or max values (max pixmap size).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by arpsmack View Post
    It doesn't matter what you put in place of the 5003. If you cast it to an A* and call a static method, its equivalent to A::print(); I think its rather unfortunate that you can even access static methods through an object... I mean it suggests that the method is somehow tied to the object, which it of course isn't as my example clearly shows.
    I'll have to agree with that. IMO, if it's static, it doesn't belong to specific instance at all, but it exists kind of like part of the blueprint or some area in-between. Thusly, it shouldn't be callable as an instance method. Madness.

    Also, in the opposite direction, I think its unfortunate that you can call a base class non-static method using A::method(); This suggests that the method is somehow tied to the class, and not the object.
    Even though the syntax is the same, I don't really think of it that way. It simply tells the compiler the scope where the function is which it should call, if not the current scope of the owning class.
    To me, it makes sense, even if it's not static.
    And casting the this pointer to something else is more of a hack, since if this is B*, then you're lying when you're telling the compiler to cast it to A* and invoke a function. Not a good thing.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointer Arithmetic and Typecasting
    By pobri19 in forum C Programming
    Replies: 2
    Last Post: 03-19-2009, 11:06 PM
  2. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  3. Replies: 2
    Last Post: 09-09-2007, 12:58 AM
  4. Direct3D problem
    By cboard_member in forum Game Programming
    Replies: 10
    Last Post: 04-09-2006, 03:36 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM

Tags for this Thread