problem with protected members

This is a discussion on problem with protected members within the C++ Programming forums, part of the General Programming Boards category; I know that protected member of a class can be accessed by subclasses of the previous class. But I have ...

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    4

    problem with protected members

    I know that protected member of a class can be accessed by subclasses of the previous class.
    But I have a problem when I compile this code

    Code:
    #include <iostream>
    using namespace std ;
    
    class A
    {
    	protected :
    		int _x ;
    	public :
    		A( int a ) : _x( a ) { ; }
    		int x() { return _x ; }
    } ;
    
    class B : public A
    {
    	public :
    		B ( int b ) : A ( b ) { ; }
    		void add ( A * a ) { if ( a ) a->_x ++ ; } 
    } ;
    
    int main()
    {
    	A a(1) ;
    	B b(5) ;
    
    	b.add(&a) ;
    	cout << a.x() << endl;
    }
    and the compiler message is
    Code:
    test.cpp: In member function ‘void B::add(A*)’:
    test.cpp:8: error: ‘int A::_x’ is protected
    test.cpp:20: error: within this context
    But if I replace the void add method of class B with
    Code:
    class B : public A
    {
    	public :
    		B ( int b ) : A ( b ) { ; }
    		void add ( A * a ) { if ( a ) static_cast<B *>(a)->_x ++ ; } // this is the line replaced
    } ;
    the program is compiled and runs well. Apparently the problem is solved but i'm not sure that this casting is 100% secure.

    Anyone knows why occurs that and how to solve it, or if that casting is secure.
    I use gcc 4.1.2

    PD: Sorry about my English, I'm a spanish speaker.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You can't access a private member of a class outside the class itself.

    The correct way to do this would be to make a function add in class A
    Code:
    void add () { _x ++ ; }
    and then implement class B add as:
    Code:
    	void add ( A * a ) { if ( a ) a->add() ; }
    Note that just because B is inheriting A, doesn't give it the right to use private members of ANOTHER A object. Casting it to a "B" object is a horrible hack and not a good solution at all.

    --
    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.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    but _x isn't a private member, is a protected one, and B is a subclass of A.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Apparently a B object has only access to the protected members of its own base part (or another B object), but not any other A object. Follow matsp's advice. Don't try to use inheritance to force your way into the protected parts of a different class.
    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).

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    Then the definiton of protected as "derived class can access to protected member of it's superclass" is incomplete because that only works if both are the same instance of the classes.

    The problem with the matsp solution is the add member of add is public and every class can access to it., thing that I won't.

    I think that the correct solution is adding to class A
    Code:
    friend class B ;
    Last edited by edwrodrig; 01-16-2008 at 07:34 AM.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    My wording was a bit incorrect. A B object can access the protected superclass parts of B objects. But if the other class is A (or C which is also derived from A) - in short, not of type B, then there's no access.

    I'd also like to point out that it is already possible to implement B::add using the public interface of A.

    Code:
    class B : public A
    {
        public :
            B ( int b ) : A ( b ) { }
            void add ( A * a ) 
            { 
                if ( a ) 
                    *a = A(a->x() + 1); 
            } 
    } ;
    Which may or may not be usable in your real code. May-be you could tell us what is actually the design problem that you are trying to solve here? Because if you have troubles like that and consider suspicious-looking casts (or making parent aware of children ) there might be problems with the broader design itself.
    Last edited by anon; 01-16-2008 at 08:29 AM.
    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).

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,886
    May-be you could tell us what is actually the design problem that you are trying to solve here? Because if you have troubles like that and consider suspicious-looking casts (or making parent aware of children ) there might be problems with the broader design itself.
    I agree, it would be wise to consider the overall picture of what you are trying to solve before reaching to make a class a friend.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    The overall problem is and double enlaced tree, in other words, parent has pointer to child and viceverse.

    Code:
    #include <iostream>
    using namespace std ;
    
    class Branch ;
    
    class Tip
    {
    	protected :
    		Tip * _parent ;
    		friend class Branch ;
    	public :
    		Tip() : _x() { ; }
    } ;
    
    class Branch : public Tip
    {
    	private :
    		CHILDREN ;
    	public :
    		Branch () : Tip () { ; }
    		void add ( Tip * a ) { if ( a ) { a->_parent = this ;  ADDTOCHILDREN( a ) ; } } 
    } ;
    
    int main()
    {
    	Branch branch() ;
    	Tip tip() ;
    
    	branch.add(&tip) ;
    }

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Wouldn't a Tree simply consist of Nodes (that contain pointers to other Nodes, below or above)? A tip would be a node whose pointers to child Nodes are NULL?

    I'm not sure why you'd need any inheritance for Nodes, but are you sure that Branch is a kind of Tip, or is it the other way round, or neither?
    Last edited by anon; 01-16-2008 at 09:33 AM.
    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).

  10. #10
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    A Branch is a type of Tip? Not evrything is an inheritance relationship.
    A Cat is a type of Mammal is a type of Animal is a type of LivingThing.
    A Branch is not a Tip, nor is a Tip a Branch.

    For a binary tree (generalize if necessary) a single Node type with dual pointers
    to children and one back to the parent, and, if you wish, perhaps a Tree type
    to hold the root and additional data. But a Node is not a Tree and a Tree is
    not a Node, so inheritance does not apply. The Tree will _contain_ Nodes
    (a Tree "has" Nodes, it is not a sub- or supertype of Node).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 05:24 PM
  2. OpenIL Texture problem
    By cboard_member in forum Game Programming
    Replies: 6
    Last Post: 12-21-2005, 12:37 AM
  3. Replies: 5
    Last Post: 11-07-2005, 10:34 PM
  4. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM
  5. binary tree problem - help needed
    By sanju in forum C Programming
    Replies: 4
    Last Post: 10-16-2002, 05:18 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21