0

I'm sorry if I am asking something that has been asked many times before here. I am very new to C++. I want to know how to make a derived class inherit copies of the private attributes of its base class. Either that, or be able to modify them via public methods, such as getters and setters, from the base class.

Essentially, I have a Person class and it inherits from the Creature class. I want Person type objects to have attributes like in the Creature class. I want to private attributes in the Creature class to stay private because I was taught that only class functions should be public, not class variables. However, I can't seem to call the Creature class's public methods in a function, and the Person class doesn't seem to inherit them or copies thereof.

The reason I am refusing to simply make the private attributes public is because I want to learn proper programming techniques. I am not sure if this situation is an exception to the rule or not.

I have cpp files that handle the implementation. Hopefully, this will be enough to help you answer my question. My Base Class:

/***
File: Creature.h
Desc: Contains Creature Class Definitions.
This is the base class for the Animal, Person, and PlayerCharacter classes.

Author: LuminousNutria
Date: 5-7-18
***/

#include <string>

#ifndef _CREATURE_H_
#define _CREATURE_H_

class Creature
{
private:
    // General Information
    std::string speciesName;
    int hitpoints;
    int movement;

    // Physical Attributes
    int strength;
    int willpower;
    int intelligence;
    int leadership;

public:
    // setters
    void setSpeciesName(const std::string a);
    void setHitpoints(const int a);
    void setMovement(const int a);

    void setStrength(const int a);
    void setWillpower(const int a);
    void setIntelligence(const int a);
    void setLeadership(const int a);

    // getters
    std::string getSpeciesName();
    int getHitpoints();
    int getLoyalty();
    int getMovement();

    int getStrength();
    int getWillpower();
    int getIntelligence();
    int getLeadership();

    // modders
    void modHitpoints(const int a);
    void modMovement(const int a);

    void modStrength(const int a);
    void modWillpower(const int a);
    void modIntelligence(const int a);
    void modLeadership(const int a);
};

My Derived Class:

/***
File: Person.h
Desc: Contains Person Class Definitions.
This is a derived class of the Creature class.

Author: LuminousNutria
Date: 5-7-18
***/


#include "Creature.h"

#include <string>

#ifndef _PERSON_H_
#define _PERSON_H_

class Person
{
protected:
    std::string personName;
    int loyalty;
    int experience;
    int level;
    int cash;

public:
    // constructors
    Person();
    Person(const std::string pName, const int loy, const int exp,
        const int lvl, const int c,
        const std::string sName, const int hp, const int mov,
        const int stre, const int will, const int intl,
        const int lead);

    // setters
    void setPersonName(std::string pName);
    void setLoyalty(const int loy);
    void setExperience(const int exp);
    void setLevel(const int lvl);
    void setCash(const int c);

    // getters
    std::string getPersonName();
    int getLoyalty();
    int getExperience();
    int getLevel();
    int getCash();

    // modders
    void modLoyalty(int a);
    void modExperience(int a);
    void modLevel(int a);
    void modCash(int a);
};

#endif

Implementation of the Creature Class's setSpeciesName method:

void Creature::setSpeciesName(const std::string a)
{
    speciesName = a;
}
LuminousNutria
  • 1,883
  • 2
  • 18
  • 44
  • Check out https://stackoverflow.com/q/224966/9225643 – MrDeal May 07 '18 at 21:04
  • 1
    [This seems to be the exact use case of `protected`](http://en.cppreference.com/w/cpp/language/access#Protected_member_access). – user4581301 May 07 '18 at 21:04
  • It's not possible to modify/access private members of the base class from the derived class directly. You need the base class to have a getter/setter or declare the variables as ```protected```. – Daniel Marques May 07 '18 at 21:05
  • @Daniel I do have getters/setters but I don't seem to know the right way to call them. – LuminousNutria May 07 '18 at 21:06
  • `setSpeciesName("Human");` should be sufficient. – user4581301 May 07 '18 at 21:08
  • 1
    On the other hand, consider using a smarter `Creature` constructor that takes parameters and [taking advantage of the Member Initializer List](http://en.cppreference.com/w/cpp/language/initializer_list) – user4581301 May 07 '18 at 21:09
  • Can you post an [MCVE]? As it stands, you don't show the `Person` or `Creature` definitions so we have to guess what they are. Also, what errors do you get when you try to call `setSpeciesName()`. – clcto May 07 '18 at 21:17
  • I will post a better example. Visual Studio says setSpeciesName is undefined. – LuminousNutria May 07 '18 at 21:22
  • To make use of that information we need to know what `Creature` and its `setSpeciesName` method looks like. Any error messages or a description of unexpected runtime behaviour would be a good idea as well. [Watch out for Object Slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing). – user4581301 May 07 '18 at 21:24
  • Setting up a simple class hierarchy as described should not cause you any problems: https://www.ideone.com/7ly4G3 – clcto May 07 '18 at 21:27
  • @user4581301 I have included the implementation of the setSpeciesName and the class declarations for the Creature class. – LuminousNutria May 07 '18 at 21:29
  • Am I missing something, or the posted code example is missing the actual inheritance? I feel like `class Person : public Creature` and using `protected` members instead of the private ones is exactly what you are looking for. – Aleon May 07 '18 at 21:31
  • @Aleon Goddammit, I'm such a dumbass! Thank you! – LuminousNutria May 07 '18 at 21:32
  • I think we can close this one as Off-topic: Typo and Friends. – user4581301 May 07 '18 at 21:49

2 Answers2

2

In the code provided, Person does not inherit from Creature, so it does not inherit the members of the Creature class.

Define your Person class as so that it inherits from Creature

class Person : public Creature
{
    // same as before
};

See Difference between private, public, and protected inheritance for more details about public vs private inheritance. Usually you want public inheritance.

clcto
  • 9,530
  • 20
  • 42
0

There are essentially two ways to solve this: 1. Explicitly call the base constructor into the derieved constructor. 2. Use the friend operator to use the private elements.

  • `friend` requires `Creature` to know all of its subclasses including any that do not exist yet. This is a maintenance problem. Just use `protected`. That's what it is for. – user4581301 May 07 '18 at 21:15