Thread: Modifying Private Members of a base class

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    7

    Modifying Private Members of a base class

    Hi,


    I am having trouble modifying a private member of a base class when using inheritance. Can please shed light on why this doesn't work and explain a workaround if one is needed.

    Code:
    class Player
    {
       public:
    
    
       virtual void setName(string s)
       {}
    
    
       private:
    
    
       string name;
    };
    
    
    class HumanPlayer : public Player
    {
       public:
    
    
       void setName(string s)
       {
          name = "h" + s;
       }
    
    
       private:
    };
    This gives me an error on compilation saying name is private and thus can't be modified. Shouldn't inheritance allow me to modify it?


    Any help is appreciated!

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The purpose in making a member private is to prevent any other code (including in derived classes) from directly modifying it.

    If you really want direct access to the member, then make it public (if you are happy for ANY other code to modify int) or protected (if you only want derived classes to have access).

    The better approach is use a public or protected member of the base class to do the work. In your case, you have setName(), so can do
    Code:
    class Player
    {
       public:
     
           virtual void setName(const std::string &s)
            {name = s;}
      
          private:
     
     
              std::string name;
    };
     
     
    class HumanPlayer : public Player
    {
       public:
     
     
       void setName(const std::string &s)
       {
            Player::setName(std::string("h") + s);       //  this calls setName() as supplied by the base class
       }
    };
    A couple of other points to note

    1) I have made string into std::string. It is a really BAD IDEA to use "using namespace std;" in a header files. Some "using" directives are okay in a header file but better to avoid them completely (most using directives have unwanted effects in a header file).

    2) Pass strings by const reference rather than by value. Copying large strings unnecessarily is not a good idea.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    7

    Command line args c strings vs c++ strings

    Quote Originally Posted by grumpy View Post
    The purpose in making a member private is to prevent any other code (including in derived classes) from directly modifying it.

    If you really want direct access to the member, then make it public (if you are happy for ANY other code to modify int) or protected (if you only want derived classes to have access).

    The better approach is use a public or protected member of the base class to do the work. In your case, you have setName(), so can do
    Code:
    class Player
    {
       public:
     
           virtual void setName(const std::string &s)
            {name = s;}
      
          private:
     
     
              std::string name;
    };
     
     
    class HumanPlayer : public Player
    {
       public:
     
     
       void setName(const std::string &s)
       {
            Player::setName(std::string("h") + s);       //  this calls setName() as supplied by the base class
       }
    };
    A couple of other points to note

    1) I have made string into std::string. It is a really BAD IDEA to use "using namespace std;" in a header files. Some "using" directives are okay in a header file but better to avoid them completely (most using directives have unwanted effects in a header file).

    2) Pass strings by const reference rather than by value. Copying large strings unnecessarily is not a good idea.
    Thanks this explained alot!!

    As a followup question:

    An example of how I run my program is
    Code:
     ./Game -p John h
    Where -p signifies the input of a user defined player name John (the John argument), who is a human player (the h argument)

    In my code I take the
    Code:
     char* argv[]
    from my main program and store it in a vector called cmdArgs like so:

    Code:
    vector<char*> cmdArgs;
    
    
    for (int i = 1; i < argc; ++i)
    {
            cmdArgs.push_back(argv[i]);
    }
    Later on I call:

    Code:
    HumanPlayer hp;
    hp.setName(cmdArgs.at(1));
    which gives me an error:

    Code:
    Game.cc:116: error: no matching function for call to âHumanPlayer::setName(char*&)â
    HumanPlayer.h:12: note: candidates are: virtual void HumanPlayer::setName(std::string&)
    I'm guessing my cmdArgs vector is not storing the
    Code:
     char* []
    only
    Code:
     char*
    ?

    I also have other functions which work perfectly with cmdArgs. For example (Don't worry about what the code means, but the fact that it uses
    Code:
     cmdArgs.at(--some number here--)
    just fine) :

    Code:
    if (static_cast<string>(cmdArgs.at(0)) == "-r")
                            {
                                    int seed = atoi(cmdArgs.at(1));
                                    mainDeck.setRandomSeed(seed);
                                    cmdArgs.erase(cmdArgs.begin(), cmdArgs.begin()+2);
                                    if (cmdArgs.size() == 0){ break; }
                            }
    What's the best way to resolve this error?

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The best way to resolve the error would be to avoid having a vector of char *'s that shadows main's argv. That is crappy design, despite the fact you claim to have other code that works perfectly with it.

    The simpler way to eliminate the compilation error (but far from the best) is to change the setName() method so it accepts a const reference to string.

    Oh, and don't use static_cast<> as a brute force means of converting to string to do a comparison. There are plenty of alternatives for doing a string comparison that will work better that don't involve unnecessary type conversions.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Initializing members of base class
    By anon in forum C++ Programming
    Replies: 8
    Last Post: 08-23-2007, 03:57 PM
  2. Can't Access the private member from base class
    By planet_abhi in forum C# Programming
    Replies: 3
    Last Post: 01-09-2006, 04:30 AM
  3. Using private class members in static functions
    By sethjackson in forum C++ Programming
    Replies: 2
    Last Post: 09-23-2005, 09:54 AM
  4. Private Static class members
    By earth_angel in forum C++ Programming
    Replies: 13
    Last Post: 08-29-2005, 06:37 AM
  5. Replies: 1
    Last Post: 12-11-2002, 10:31 PM

Tags for this Thread