-1

I have three classes:

Class Something
{...}

Class A
{
public:
    A();
    virtual ~A() = 0; //have also tried this as non-abstract

    std::vector< unique_ptr<Something> > somethings; //have tried this just as std::vector<Something*> as well
};

class B : public A
{
    B();
    ...
}

if I leave out the declaration of std::vector< Something* > somethings, from class B... then my compiler tells me that class class ‘B’ does not have any field named ‘somethings’.

So if I add it back in, and I try to reference it like so

A *a = new B();

for(auto it = a->somethings.begin(); it != a->somethings.end(); it++)
{
     Draw((*it)->image,(*it)->x, (*it)->y, NULL, (*it)->angle);
}

It says that a->somethings is empty... even though if I print from B itself to tell me how many 'somethings' there are, it is accurately reporting the count. This is what led me to remove std::vector< unique_ptr > somethings; from class B to begin with, as I suspected it was somehow getting A's vector instead, even though it's abstract.

Bonus: This all works if I go B *b = new B(); just broke when I added the parent class A and made B inherit from it.

zmartin
  • 211
  • 1
  • 2
  • 7
  • 1
    `somethings` is private... – yizzlez Jun 11 '14 at 21:14
  • @DrewDormann somethings is public in my code, as is B : public A, but I felt it detracted from the point to include. EDIT: I have included it, now for clarity. It is also important because of the Draw function accessing the member somethings. – zmartin Jun 11 '14 at 21:24
  • http://coliru.stacked-crooked.com/a/c2913bfcccbe407d - I have compiled an example – zmartin Jun 11 '14 at 21:25
  • Is there a "somethings" in the B class as well? If so post the complete code – Marco A. Jun 11 '14 at 21:25
  • @zmartin You shouldn't be initializing member variables in a derived constructor, that would destroy encapsulation at the very least – Marco A. Jun 11 '14 at 21:27
  • @MarcoA. The "somethings" was there at first, exactly as it looked in the class A, and the code compiles that way.... but the Draw() function accesses the object pointed to by A *a = new B(); and somethings is all of a sudden empty. This is why I removed it from B, as I suspected it was not actually accessing B's 'somethings', which it was not (because a print FROM B tells me there is content in the vector). Thank you for the responses, please keep 'em coming. – zmartin Jun 11 '14 at 21:28
  • 1
    @zmartin Please post **the real code** in your question. The code in your question doesn't exhibit the problem you describe. – Drew Dormann Jun 11 '14 at 21:28
  • @DrewDormann It does exhibit the problem, and is just a simplified version of the real code that I have now posted. Ty. – zmartin Jun 11 '14 at 22:13

2 Answers2

3

From the linked code in your comment, the problem is that you're trying to initialize the base class field directly in the derived class. You can't do that (and it makes no sense to try) as the base class fields are initialized by the base class constructor. If you want to initialize the field (rather than assigning to it), you need to do it in the base class constructor:

class Base {
public:
    std::vector<float> fVec;
    Base(std::vector<float> v) : fVec(v) { }
};

class Derived : public Base {
public:
    Derived(std::vector<float> v) : Base(v) {
        :

Note that the code you show above is completely different from and unrelated to what you linked to -- you should post the code that pertains to your question, and not unrelated irrelevant code.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • Code added, ty for the response - The main point of the code I linked is the error generated - whether it is initialized in constructor or not, the derived class does not own a std::vector fVec. The error is the same if you move it from the constructor to letting Dervied populate it itself. – zmartin Jun 11 '14 at 21:42
  • Nothing, now? Everybody was so quick to take a brief glance at my code, critique the hell out of it, and yet provide nothing valuable. Your answer still doesn't work, and I'm not initializing the base class' values anywhere. I care about the derived class' vector, and I initialize it and populate it within the class. I access it outside the class, via the draw function with a Weapon * mainWep = new BowAndArrow(); I deserve my downvote taken back =/ you didn't even bother to read the compiler output on the page I linked. – zmartin Jun 11 '14 at 22:06
  • @zmartin: the derived class has access to the field in the base class (unless you make it private), so it doesn't need (and shouldn't have) its own field. The only way the error you show comes up is if you [incorrectly attempt to initialize the field in the derived class](http://coliru.stacked-crooked.com/a/c2913bfcccbe407d), which can be fixed as I show here. No other code you've shown has any apparent errors at all... – Chris Dodd Jun 11 '14 at 22:21
  • Thanks for the response. The code still generates the same error, and after hours of messing with it and building a test example that produces the same thing, I'm giving up and scrapping it all, just like this post. Thank you! – zmartin Jun 11 '14 at 22:26
0

I'm not sure if this will help you, but I made a small change to your coliru.stacked-crooked example as follows:

#include <vector>

class Base
{
public:
    std::vector<float> fVec;
};

class Derived : public Base
{
public:
    Derived(std::vector<float> v) // : fVec(v)
    {
        fVec = v;
    }
};
int main() {}

Notice I commented out the fVec from the constructor initialisation list and assigned it in the body of the constructor. The problem here is that your Base object hasn't been created fully until you enter the opening brace of the body of your Derived constructor.

To work around this issue, you could add a constructor to your Base object that takes a vector and then assign that to your object, more or less what Chris said.

Both examples above work for me, but I don't have your full code so can't be sure they'll fix all your problems. I thought I'd take a punt anyway.

You probably know all about the copies of vectors being made and should be passing them as const refs, but that's another issue.

djikay
  • 10,450
  • 8
  • 41
  • 52