views:

159

answers:

4

I'm having some problems with inheritance and constructors in C++. What I've got is a class VirtualMotor which inherits Motor (is that the correct way to say it?). The class VirtualMotor should have it's own constructor, but I'm doing something wrong when I create it and the compiler gives me an error (se below). My source code is like this:

Motor.h

class Motor
{
protected:
    float speed;
    float angle;
public:
    Motor();
    float getSpeed();
    float getAngle();
    virtual void setSpeed( float speed );
    virtual void setAngle( float angle );

Motor.cpp

#include "Motor.h"

float Motor::getSpeed() { return speed; }
float Motor::getAngle() { return angle; }

VirtualMotor.h

#include "Motor.h"

class VirtualMotor: public Motor
{
private:
    float lastSpeed;
public:
    VirtualMotor();
    void setSpeed(float speed);
    void setAngle(float angle);
};

VirtualMotor.cpp

#include "VirtualMotor.h"

VirtualMotor::VirtualMotor() 
{
    speed = 2;
    angle = 5;
}

void VirtualMotor::setSpeed(float speed)
{
    this->speed = speed;
}

void VirtualMotor::setAngle(float angle)
{
    this->angle = angle;
}

Main.cpp

#include <iostream>
#include "VirtualMotor.h"

using namespace std;

int main (int argc, char **argv)
{
    VirtualMotor m;
    cout << m.getSpeed() << endl;
    m.setSpeed(9);
    cout << m.getSpeed() << endl;   

    return 0;
}

To compile I use the command g++ Main.cpp Motor.cpp VirtualMotor.cpp -o main and I get the following error:

/tmp/ccIdYJaR.o: In function `VirtualMotor::VirtualMotor()':
VirtualMotor.cpp:(.text+0x29): undefined reference to `Motor::Motor()'
/tmp/ccIdYJaR.o: In function `VirtualMotor::VirtualMotor()':
VirtualMotor.cpp:(.text+0x5d): undefined reference to `Motor::Motor()'
/tmp/ccIdYJaR.o:(.rodata._ZTI12VirtualMotor[typeinfo for VirtualMotor]+0x8): undefined reference to `typeinfo for Motor'
collect2: ld returned 1 exit status

I feel there's a really simple solution to this, but I just can't see it. I've tried to use VirtualMotor::VirtualMotor() : Motor::Motor() and other variations without any luck.

+2  A: 

You've declared a default constructor for the class Motor in Motor.h (Motor(); immediately below public:), but you haven't given it a definition in Motor.cpp.

Paul Baker
That's true. I've added Motor::Motor() { speed = 4; angle = 8; }to Motor.cpp.Now I get a similar error, but for the Motor() constructor: /tmp/cc7Nuinq.o: In function `Motor::Motor()': Motor.cpp:(.text+0x2c): undefined reference to `vtable for Motor' /tmp/cc7Nuinq.o: In function `Motor::Motor()': Motor.cpp:(.text+0x52): undefined reference to `vtable for Motor' /tmp/ccxlGOhT.o:(.rodata._ZTI12VirtualMotor[typeinfo for VirtualMotor]+0x8): undefined reference to `typeinfo for Motor' collect2: ld returned 1 exit status
Paul
You also haven't implemented setSpeed and setAngle in Motor.cpp. Either implement these or, if you wanted these functions to be pure virtual, declare them as "virtual void setSpeed( float speed ) = 0;" and "virtual void setAngle( float angle ) = 0;"
Paul Baker
+5  A: 

In your code you declare the Motor() constructor but never provide an implementation for it. Also, you don't seem to be using include guards in your header files. motor.h should look something like this (although this isn't to do with the problem you are asking about):

#ifndef INC_MOTOR_H
#define INC_MOTOR_H

class Motor
{
   ... // your stuff here
};
#endif

And lastly, protected data is generally a bad idea.

anon
+1 **protected data is generally a bad idea**... I have tried to explain it to my colleagues and they usually just shrug it off as *it's easier* ...
Matthieu M.
A: 

Add in motor.cpp

Motor::Motor(){
}
Victor Hurdugaci
+2  A: 

As the others mentioned, Motor()'s definition is missing. The easiest way would be to change its declaration to 'Motor() {}'. This way is cleaner, however:

class Motor {
  protected:
     Motor(float speed, float angle)
      : speed(speed), angle(angle)
     {}

  public: .
}
...
VirtualMotor :: VirtualMotor
  : Motor(2,5)

So you don't have to initialize base class members directly from within VirtualMotor's c'tor.

Alexander Gessler