Thread: Bungled Inheritence: Layered Constructors

  1. #1
    Registered User
    Join Date
    May 2003
    Posts
    37

    Bungled Inheritence: Layered Constructors

    I'm *positive* someone has asked this before...but I couldn't find it in the search, sorry, so I'm asking again.

    I have a base class called Object, with the following constructor:

    Object.cpp:
    Code:
    Object::Object()
    {
    	burnable = false;
    	edible = false;
    	equipable = false;
    	wearable = false;
    			
    	keyID = -1;  // not a key
    	lockID = -1; // not a lock
    	
    	name = "New Object.";
    	floorDescription = "A dusty new object lies on the floor.";
    }
    All those variables that are modified there are PRIVATE Object variables.

    Now, I have a class Container, which is an extention of Object. I do the following:

    Container.h:
    Code:
    class Container : public Object
    Container.cpp:
    Code:
    Container::Container()
    {
    	Container::Object();
    	
    	floorDescription = "You spy a new container lies here.";
    	name = "New Container";
    	isOpen = false;	
    }
    This is to avoid resetting all the params to default values again in the Container constrcturo. This works fine, except when I try to modify floorDescription and name (private fields in Object class), I get the following errors:

    std::string Object::floorDescription' is private Object.h

    std::string Object::name' is private Object.h

    Any ideas?

  2. #2
    Grammar Police HybridM's Avatar
    Join Date
    Jan 2003
    Posts
    355
    I may be wrong but I don't think derived classes will inherit private members of base, I think you can use the protected key word for this.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by HybridM
    I may be wrong but I don't think derived classes will inherit private members of base, I think you can use the protected key word for this.
    Correct. Derived classes only inherit public members and methods.

    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    May 2003
    Posts
    37
    Ahhhhhhh, I knew it was something absurdly simple! Thanks!

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Three ideas:

    1) You don't need the line Container::Object(); The base class constructor is called automatically. In this case that is all you need since there are no arguments for your constructor.

    2) All member variables that are private cannot be accessed by derived classes. If you want to allow them to be accessed by derived classes but not be other classes then you would make them protected. Some people would say that making member variables protected is indicative of a design flaw, but for the purposes of your problem that would fix it.
    Originally posted by quzah
    Derived classes only inherit public members and methods
    You meant protected, not public, right?

    3) Just a side note, a better way to initialize those variables could be like this (assuming all are declared protected):
    Code:
    Object::Object() : burnable(false),
    	edible(false),
    	equipable(false),
    	wearable(false),
    	keyID(-1),  // not a key
    	lockID(-1) // not a lock
    	name("New Object."),
    	floorDescription("A dusty new object lies on the floor.")
    {
    }

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    37
    Hmm, I never knew you could do that...thanks, I'll try it.

  7. #7
    Registered User
    Join Date
    May 2003
    Posts
    37
    Ahhh, awesome, it works, minus the following constructer, which gives me a "Parse error before { token":

    Code:
    Room::Room(string newDesc, int newNorth, int newEast, int newSouth, int newWest, int newTop, int newBottom) :
    
    	description(newDesc),	
    	northRoom(newNorth),
    	eastRoom(newEast),
    	southRoom(newSouth),
    	westRoom(newWest),
    	topRoom(newTop),
    	bottomRoom(newBottom),
    {
    }
    This notation is new to me...I like it, but I don't quite understand it...

  8. #8
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Remove the comma at the end of bottomRoom(newBottom), to get rid of the parse error.

    Its called an intialization list. You can search for more information or somebody who has more time/knowledge can give you detailed information. I would guess there is already good info about them in this forum.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by jlou
    You meant protected, not public, right?
    No. I ment public:
    Code:
    class Foo {
        public:
            void Fooie( void )
            {
                cout << "Fooie " << endl;
            }
    };
    
    class Bar : public Foo {
        public:
            void ReBar( void )
            {
                Fooie( );
                cout << " Bar!" << endl;
            }
    };
    
    Bar b;
    b.ReBar( );
    See?

    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    37
    Ach, so embarrased..can't believe I missed that comma.

    Derived classes inherit protected fields too, I think, is what the guy was trying to say...

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Yeah. It would have been best said, "They do not inherit private members and methods.", I suppose.

    Quzah.
    Hope is the first step on the road to disappointment.

  12. #12
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Originally posted by quzah
    Correct. Derived classes only inherit public members and methods.
    Yes, my wording was wrong also. I meant to say that in addition to public members and methods, derived classes also inherit protected members and methods.
    Code:
    class Foo {
        protected:
            void Fooie( void )
            {
                cout << "Fooie " << endl;
            }
    };
    would work.

  13. #13
    Grammar Police HybridM's Avatar
    Join Date
    Jan 2003
    Posts
    355
    why are classes using protected supposedly badly designed?
    Last edited by HybridM; 07-29-2003 at 07:17 PM.
    Thor's self help tip:
    Maybe a neighbor is tossing leaf clippings on your lawn, looking at your woman, or harboring desires regarding your longboat. You enslave his children, set his house on fire. He shall not bother you again.

    OS: Windows XP
    Compiler: MSVC

  14. #14
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    What I meant was not that using protected is bad design, but rather that making base class member variables protected might be considered bad design.

    I actually do that all the time, but there are some who say that in perfectly designed object oriented code, data should be encapsulated. This includes hiding base class data from derived classes and only exposing access methods for the data that should be allowed to be modified or seen by the derived classes.

    I'm sorry I can't provide a reference to a book or article that makes that declaration. Like I said, I break that "rule" all the time because in my coding situations I'd rather be able to code quickly than take the time to follow perfect OOP techniques. To me this case is a VERY trivial issue. There are so many other ways that I and other programmers can improve design. I just mentioned it because I didn't want to blindly recommend something that might be considered bad design.

  15. #15
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Protected isn't bad. Protected is just bad *for variables*. Herb Sutter has asserted that variables should never be anything other than private (with the exception of the public variables forming struct-like classes which do nothing more than bundle data togather, and have no methods). Protected should be used for methods and methods alone, just like public.

    The reason is thus: methods are your interface, variables are your implementation, and NOTHING outside of the class, not even child classes, should have direct access to the implementation. Everything outside of the class itself* should access the class only through its interface, be it a public or protected interface.

    If you want the child to be able to modify properties that others can't, use protected member functions. Not protected variables.

    * Note: functions designed to operate on a class, and bundled with that class, count as part of the class itself. An example is a friend ostream & operator << (ostream &o, const MyClass & c). Even though it's not in the body of the class, for all intents and purposes, it is a part of the class's public interface. It is part of the implementation of the class.
    Last edited by Cat; 07-29-2003 at 10:46 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Arrays and Constructors
    By Verdagon in forum C++ Programming
    Replies: 1
    Last Post: 07-20-2005, 07:20 PM
  2. constructors, arrays, and new
    By Thantos in forum C++ Programming
    Replies: 6
    Last Post: 05-30-2004, 06:21 PM
  3. Throwing exceptions with constructors
    By nickname_changed in forum C++ Programming
    Replies: 14
    Last Post: 07-08-2003, 09:21 AM
  4. Copy constructors and private constructors
    By Eibro in forum C++ Programming
    Replies: 5
    Last Post: 11-24-2002, 10:16 AM
  5. Default Constructors
    By MethodMan in forum C++ Programming
    Replies: 2
    Last Post: 10-25-2002, 06:30 PM