-1

I have a class called A with the following definition:

class A {
public:

    int time;
    A *next; 
    someFunc();
    A();
    virtual ~A();
};

I have a subclass of A, called B, with the following definition:

#include "A.h"

class B : public A {
public:

    int state;
    Foo *ID;
    someFunc();
    B(int time, A *next, int state, Foo *id);
    virtual ~B();
};

B's constructor is defined as:

B::B(int time, A *next, int state, Foo *id) : time(time), next(next), state(state), ID(id) { }

When I build the program, I get an error that class B has no fields named "time" or "next." I made sure that I have A.h included in the B.h file as well as the B.cpp file but it seems not to make a difference. Notably, someFunc() in class B is recognized. I define a body different from class A's version in B.cpp. At the declaration in B.h, Eclipse has a marker reminding me it "shadows" A::someFunc(), so I know B has inherited at least that.

I am working on this program in Eclipse and using a makefile to build it. My line for building B.o is:

B.o: B.cpp B.h
    g++ -c -Wall -g B.cpp

I have also tried adding A.h at the end of the first line, which does nothing. Am I missing something from here that could cause this error?

J. Cal
  • 157
  • 1
  • 3
  • 18

4 Answers4

1

You can't initialize the members of base class, it's supposed to be the base class's responsibility.

You can add a constructor which initilizing such members for A:

class A {
public:   
    int time;
    A *next; 
    someFunc();
    A();
    virtual ~A();
    A(int time, A* next);
};

A::A(int time, A *next) : time(time), next(next) { }

then

B::B(int time, A *next, int state, Foo *id) : A(time, next), state(state), ID(id) { }

Or assign them in B's constructor if you can't add the constructor for A:

B::B(int time, A *next, int state, Foo *id) : state(state), ID(id) {
    this->time = time;
    this->next = next;
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

You used the same names for your parameters so they are "hiding" the members. You can do something like this in the constructor body:

this->time = time;
this->next = next;
Marker
  • 972
  • 6
  • 9
0

A constructor initialization list can only initialize its own class members, not members of its parent. What you typically want to do is use the constructor of the parent to initialize those.

class A {
public:

    int time;
    A *next; 
    someFunc();
    A(int time, A *next) : time(time), next(next) {}
    virtual ~A();
};

class B : public A {
public:

    int state;
    Foo *ID;
    someFunc();
    B(int time, A *next, int state, Foo *id) : A(time, next), state(state), ID(ID) {}
    virtual ~B();
};
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

The class B do have the members from A. But they are not in scope of the constructor initializer list. You have to create an A constructor taking the arguments you want to pass on to A:

class A {
public:

    int time;
    A *next; 
    someFunc();

    A(int time, A* next)
        : time(time), next(next)
    {}

    virtual ~A();
};

class B : public A {
public:

    int state;
    Foo *ID;
    someFunc();

    B(int time, A *next, int state, Foo *id)
        : A(time, next), ID(id)
    {}

    virtual ~B();
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621