Quick inheritance question

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • djboyse
    New Member
    • Apr 2007
    • 9

    #1

    Quick inheritance question

    Hey, just a quick question about inheritance.

    Heres some basic code to try explain...

    class base
    {
    public:
    object1 anObj;
    void setName(void);
    };

    void base::setName(v oid) { anObj.giveName( "name"); }

    class derived : base
    {
    public:
    object2 anObj;
    };

    Ok so object1 and object2 both have the giveName(string ) method. The global object anObj changes type, but the giveName() method is still valid. So i guess im trying to ask if its possible for object2 anObj to override object1 anObj so that derived::setNam e() will set the name of object2 anObj?
  • Ganon11
    Recognized Expert Specialist
    • Oct 2006
    • 3651

    #2
    Yes. In your derived class, add the method setName(void), which can call base::setName() , and then call anObj::giveName ("whatever") . You should also declare setName as virtual in base and derived, so that if you ever pass a derived to a function that takes a base, it will call the proper setName function.

    Comment

    • djboyse
      New Member
      • Apr 2007
      • 9

      #3
      Thanks for the speedy reply.

      If I add the setName method to derived, won't that kind of defeat the point of having a derived class?

      I want to use the setName function in base to set the name of the object2 in derived. Adding the same method to derived will just be duplicating the code, which is what i'm trying to avoid.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        This is not a yes or no question.

        True, adding a setName() method to your derived class would hide the setName() method in the base class but there are times when you want this behavior.

        Maybe the base class is a Door with an Open() method and things go along OK until the boss wants a Door that can be opened only with a magic spell. So you derived EnchantedDoor friom Door and implement the Open() in EnchantedDoor to reauire a magic spell:

        class Door
        {
        public:
        Open();
        };

        class EnchantedDoor :public Door
        {
        public:
        Open(char* thespell);
        };

        In your application:

        Door d;
        d.Open(); //opens the door
        EnchantedDoor d1;
        d1.Open("Sesame "); //uses magic spell to open the door


        This type of situation is common when writing factory classes.

        Comment

        • djboyse
          New Member
          • Apr 2007
          • 9

          #5
          I don't think I'm explaining my problem properly. Sorry Ill try again with more relevant names.

          Say I'm making an MP3 player simulator. Ill have an Track object and a Player object. I also have Mp3Player which is derived from Player and and Mp3Track which is derived from Track...

          class Track
          {
          public:
          string name, artist;

          string getName(void) { return name; }
          sting getArtist(void) { return artist; }
          };

          class Mp3 : public Track
          {
          public:
          string album;

          string getAlbum(void) { return album; }
          };

          class Player
          {
          public:
          vector *playList;
          Track *currentTrack;

          void setCurrentTrack (int num) { currentTrack = playList.at(num ); }
          void showTrackName(i nt trackNum)
          {
          setCurrentTrack (trackNum);
          cout << currentTrack->getName();
          }
          };

          class Mp3Player : Public Player
          {
          Mp3Track *currentTrack;

          void showTrackAlbum( trackNum)
          {
          setCurrentTrack (trackNum);
          cout << currentTrack->getAlbum();
          };

          So when an Mp3Player is created, it overrides currentTrack so it becomes a Mp3Track, so when Player::setCurr entTrack() sets the track, it is setting an Mp3Track. Also if the showTrackName() method were to be called, it would be getting the name of an Mp3Track. Ive tried implementing this and instead of showTrackName() returning the name of an Mp3Track, it tries to return the name of a Track, which isn't there.

          Am i trying something that cant be done, or am i just goin about it the complete wrong way?

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            This statement is not correct:

            So when an Mp3Player is created, it overrides currentTrack so it becomes a Mp3Track,

            When an Mp3Player is created is has a member variable:

            Mp3Track *currentTrack;

            which is used by the Mp3Player::setC urrentTrack(). Except that there is no such method. All there is is this: void Player::setCurr entTrack() and this method uses the:

            Track *currentTrack;

            of the Player class.

            Remember a compund object contains an instance of each of its base classes and data members do not override other data members. Only member functions can override member fuinctions.

            It's starting to look like you want to implement the "Mp3Player" IS A KIND OF "Player". If that's the case, you need to use polymorphism:

            class Player
            {
            Track* currentTrack;
            public:
            virtual void setCurrentTrack (int num);
            };

            class Mp3Player : public Player
            {
            public:
            virtual void setCurrentTrack (int num);

            }


            void AFunction(Playe r* p)
            {
            p->setCurrentTrac k(25);
            }

            Now you create an Mp3Player object and use it as a Player object:

            Mp3Player* obj = new Mp3Player;

            AFunction(obj); //inside it calls Mp3Player::setC urrentTrack

            Player obj1;
            AFunction(obj1) ; //inside it calls Player::setCurr entTrack


            Is this what you have in mind?? If so, read up on virtual functions.

            Comment

            • djboyse
              New Member
              • Apr 2007
              • 9

              #7
              Yeah, thats what I'm trying to do. Thanks for pointing me in the right direction. Much appreciated.

              Comment

              Working...