0

I have a base class A and in this class, there is a vector of the derived class B, and I add class C objects to this list (C is a derived class of B).
But now I am not able to access any variable either from B or C.

My class structure goes like this:

enter image description here

Skill.h

class Skill
{

public:

    Skill()
    {

    }

    vector <AttackSkill*> attacks;
    vector <UtilitySkill*> utilities;
    vector <MoveSkill*> movement;

};

AttackSkill.h

#pragma once
#include "Skill.h"

class AttackSkill :
    public Skill
{

public:

    AttackSkill()
    {

    }

    string skillName;       
    int dmgMod;
    int baseAcc;

};

One of the skills

#pragma once
#include "AttackSkill.h"

class Axeblade :
    public AttackSkill
{
public:
    Axeblade()
    {
        skillName = "Axeblade";     
        dmgMod = 0;
        baseAcc = 72;
    }

};

This is how to add new skill

attacks.push_back(new Axeblade);

I just want to be able to access variables.

Example:

"skillPtr" is a pointer to Skill object

for (int i = 0; i < skillPtr->attacks.size(); i++) //No problem here
{
    cout << "Skill " << i << ") " << skillPtr->attacks[i]->skillName << endl;
}

Error C2039 'skillName': is not a member of 'Skill'

Someone
  • 15
  • 5
  • 2
    Do you really want to have/inherit vector members in sub classes? – Jarod42 May 13 '20 at 11:28
  • 1
    What do you mean by "But now I am not able to access any variable either from B or C.".?Do you get some kind of error message? – luxun May 13 '20 at 11:29
  • @Melebius Well there are multiple skills and I have a character that I want to be able to add and remove skills from. – Someone May 13 '20 at 11:41
  • 1
    This is not related to what I was speaking about. By inheriting `Skill`, you are getting those three vectors in each subclass. And please show us a [mcve]. Too many things remain unclear as you presented just bits of your code. In a comment you speak about `heroes[0]` but how is it defined?! http://idownvotedbecau.se/nomcve/ – Melebius May 13 '20 at 11:45
  • @Melebius Ah okay I just understood you, I added an example. Also i was confused i wanted to say attacks[0], not heroes it is not important to our topic. – Someone May 13 '20 at 12:00
  • 1
    Following your code sample, I tried to do a complete reproducer: https://godbolt.org/z/HiwDad . What is your question on this example? (NB: I use unique_ptr as a good practice to avoid memory leaks) – Pascal H. May 13 '20 at 12:03
  • I just tried @PascalH.'s solution. It works perfectly fine. If you even write ` std::cout << h.skillPtr->attacks[0]->skillName << std::endl;;` in his code (don't forget to include ) then it prints Axeblade. – StefanKssmr May 13 '20 at 12:09
  • 2
    With the error 'Error C2039 'skillName': is not a member of 'Skill'' I assume that in your code (not here in your sample) `attacks` field should be a `vector ` not a `vector `. Is it right? – Pascal H. May 13 '20 at 12:11

1 Answers1

0

I am doing some guesswork here since the question is not fully specific but it might help…

Your class Skill contains three vectors (aggregation) and it’s inherited by subclasses defining skill types (inheritance). You should break these two principles apart. There should be one class containing the vectors for a character, let me call it SkillSet. (By the way, you should never issue using namespace in a header file.)

class SkillSet
{
public:
    std::vector <AttackSkill *> attacks;
    std::vector <UtilitySkill *> utilities;
    std::vector <MoveSkill *> movement;
};

Then there will be another base class for all skills which would contain the properties which all skills have:

class Skill
{
public:
    std::string skillName;       
};

Then you can inherit this new Skill class:

class AttackSkill :
    public Skill
{

public:
    int dmgMod;
    int baseAcc;
};

class Axeblade :
    public AttackSkill
{
public:
    Axeblade()
    {
        skillName = "Axeblade";     
        dmgMod = 0;
        baseAcc = 72;
    }
};

After creating and filling a SkillSet object:

SkillSet hero0;
hero0.attacks.push_back(new Axeblade);

You can simply access its public members:

std::cout << hero0.attacks[0]->skillName;

See the example of my code.

A few more notes to consider:

  • You don’t need vectors of pointers, you can put the objects directly to the vector. A vector is not a plain array.
  • Instead of making the properties public, consider using setters and getters.
  • Your code contains empty constructors. There is no need to write a constructor that is empty.
  • On the other hand, if your code contains objects created using new, you should delete them, e.g. in a destructor.
Melebius
  • 6,183
  • 4
  • 39
  • 52