![]() |
|
Inheritage visibility in C++ - Printable Version +- iDevGames Forums (http://www.idevgames.com/forums) +-- Forum: Development Zone (/forum-3.html) +--- Forum: Game Programming Fundamentals (/forum-7.html) +--- Thread: Inheritage visibility in C++ (/thread-4752.html) |
Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 12:24 AM Hello. I'm having problems with the visibility of symbols declared protected. I have two classes, Spatial and Node (will be a very simplified version of the scenegraph in “3D Game Engine Architectureâ€, by David Eberly) Code: class Spatial { and Code: class Node : public Spatial {where addChild is implemented like this: Code: void Node::addChild(Spatial* child) {I get the error “void Spatial::set_parent(Spatial*) is protected within this contextâ€. I can't see what the problem is. Shouldn't protected symbols in base classes be accessible? Inheritage visibility in C++ - Fenris - Nov 28, 2005 12:51 AM I've had that too, it's XCode not being very clear. The error is split over two lines, right? void Spatial::set_parent (Spatial*) is protected <-- shows what is protected within this context <-- shows where you're trying to access it The two lines jump to differents places in your code.
Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 01:41 AM Yes, that's right. It is split over two lines (I originally read it as being the same continued message, but now that you point it out, I see what you mean). That doesn't tell me any more about what the problem is though. Why exactly can't I access a symbol declared protected in a base class? I thought the point of the protected declaration was specifially so that one could use parts of base classes within inheritance trees, but not from the outside. Thanks for the clarification on the error message though. Inheritage visibility in C++ - TomorrowPlusX - Nov 28, 2005 07:19 AM I could be wrong but I don't believe you can call protected methods on a *different* object, even if you're derived from it. E.g., you could call the inherited protected method if the target object is 'this', but not if it's a different object. This might call for a refactoring. Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 11:21 AM Wow, do I feel stupid. I didn't even think about that. Anyway, any suggestions how to do this then without declaring set_parent public? Inheritage visibility in C++ - NCarter - Nov 28, 2005 11:51 AM Add this: Code: friend class TheOtherClass;Inheritage visibility in C++ - DDustin - Nov 28, 2005 02:11 PM Quote:I could be wrong but I don't believe you can call protected methods on a *different* object, even if you're derived from it.This can't be true... Maybe you should make a test case, that would clear things up. Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 02:40 PM NCarter: Not really general enough, as I want the whole tree of classes to be able to use the functionality. DDustin: I already made the test case (stripped all code except the code in question), and this seems to be the case. Logical enough, when I think about it. In most circumstances I probably wouldn't want two objects (even of the same class) to be able to use each others protected methods/variables. Inheritage visibility in C++ - sealfin - Nov 28, 2005 02:57 PM ermitgilsukaru Wrote:In most circumstances I probably wouldn't want two objects (even of the same class) to be able to use each others protected methods/variables. But they can if those methods are 'private', and (until now...) I believe that 'protected' is weaker protection than 'private'? I'm pretty sure you're wrong... A little later: I was right, 'protected' is weaker protection than 'private' (or at least, not as strong as you thought); here's a trite little test case of calling a 'protected' method of another object: Code: #include <stdio.h>Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 03:25 PM Hmmm. I just tried to compile this code: Code: class Base {...and it doesn't work. Sealfin has with his test-code established that within a class two instances have automatic friend status (and when looking at earlier code I've written, I see that is the case). So the problem must have something to do with the rules of inheritance of friend status. (sorry for the convoluted phrasing) Inheritage visibility in C++ - sealfin - Nov 28, 2005 03:57 PM ermitgilsukaru, this is your test case with a minor alteration: you needed to upcast (terminology?) to Derived the call to the 'protected' Base method (I presume you meant object 'b' in main() to be of the Base class, but it works either way.) Code: #include <stdio.h>Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 04:55 PM sealfin: Is this really safe if I have other classes derived from Base, but not from Derived? I.e: Base | -------------- | | Derived AnotherSibling I tried building such a test case, and it compiled, but I'm really not comfortable with this. For example; if I decided to make another protected function in Base, and this one virtual, when doing the above trick the Derived function would run, even if the original pointer was from another branch of the class tree. Even so, you solution is probably the best one yet. Inheritage visibility in C++ - ermitgilsukaru - Nov 28, 2005 05:05 PM Crap. My intricate and detailed ASCII art wasn't reproduced faithfully. Curse you, non whitespace-preserving semantics of HTML! Anyway, here it is all wrapped in [ code ] tags: Code: BaseInheritage visibility in C++ - zKing - Dec 9, 2005 09:44 PM Lemme try an explaination... This will work: Code: void Node::addChild(Spatial* child) This will work: Code: void Node::addChild(Spatial* child) And as we know, (the curious case)... this does NOT work: Code: void Node::addChild(Spatial* child) Why? Because the compiler knows this is some kind of "Spatial", BUT it could be some OTHER derived class of "Spatial". It's a little bit of splitting hairs, but I believe its done that way because if I inherit from "Spatial" to create a class "Foo" and I see something that is "protected", I expect that only "Spatial" or "Foo" will ever call that protected method on instances of "Foo". This way I can assume things about the state of my "Foo" objects. I don't want some "Node" object being able to touch my protected stuff (unless its through public Spatial stuff I already know about). Clear as mud? |