4.6 KiB
Demonstration of Class Definition in C++
This first example makes use of the default constructor, but this is problematic due to initialization.
Robot.h
class Robot {
private:
float directionAngle;
int position[2];
public:
void moveForward( int distance );
void display();
};
Robot.cpp
#include "robot.h"
#include <math.h>
#include <iostream>
void Robot::moveForward(int distance) {
position[0] = position[0] + distance*cos(directionAngle);
position[1] = position[1] + distance*sin(directionAngle);
}
void Robot::display() {
cout << "Pos [" << position[0] << " " << position[1] << "]. angle "
<< directionAngle << endl;
}
main.cpp
In C++, main() serves as the entry point to the program. It must exist to generate an executable.
#include "robot.h"
#include <iostream>
using std::cout;
int main() {
Robot rosyRobot;
rosyRobot.display();
}
You can compile the program using the provided makefile, then call the executable robot.
make
./robot
We will fix the initialization problem by adding "setters" and add some "getters" while we are at it.
Robot.h
class Robot {
private:
float directionAngle;
int position[2];
public:
// setters and getters
void position( int x, int y);
int* position();
void radianDirectionAngle(float theta);
float radianDirectionAngle();
void moveForward( int distance );
void display();
};
Robot.cpp
Adding the following to the source code.
// setters and getters
void Robot::xyPosition( int x, int y) {
position[0] = x;
position[1] = y;
}
int* Robot::xyPosition() {
return position;
}
void Robot::radianDirectionAngle(float theta) {
directionAngle = theta;
}
float Robot::radianDirectionAngle() {
return directionAngle;
}
main.cpp
int main() {
Robot rosyRobot;
rosyRobot.xyPosition(0,0);
rosyRobot.radianDirectionAngle(0);
rosyRobot.display();
}
This is dangerous to require users to initialize. Let's fix this by forcing the user to provide initialization.
Adding to Robot.h
We can pass along an array, but let's not do that right now. We will see why later.
Robot( int x, int y, float theta );
Adding to Robot.cpp
Robot( int x, int y, float theta ) {
position[0] = x;
position[1] = y;
directionAngle = theta;
}
This can be cumbersome, let's give the user some options.
OPTION 1: Add a no-parameter constructor that initializes to reasonable values.
Adding to robot.h
public:
Robot();
Adding to robot.cpp
Robot::Robot() {
position[0] = 0;
position[1] = 0;
directionAngle = 0;
}
Change main.cpp
int main() {
Robot rosyRobot;
rosyRobot.display();
}
OPTION 2: Add a constructor with a subset of the member variables.
Adding to robot.h
public:
Robot();
Robot( int x, int y );
Robot(float theta);
Then you will add these definitions to robot.cpp. Let's see how we use them.
main.cpp
int main() {
Robot rosyRobot;
Robot c3poRobot(100,100);
Robot halRobot(0,0,3.14/2);
Robot eveRobot(-100,-100,-3.14/4);
rosyRobot.display();
c3poRobot.display();
halRobot.display();
eveRobot.display();
}
Looks like this when you run it ...
Pos [0 0]. angle 0
Pos [100 100]. angle 0
Pos [0 0]. angle 1.57
Pos [-100 -100]. angle -0.785
OPTION 3: (Probably the best) Create a single constructor that can take 1 to all member variable initializations.
Now we have to undo some of our work. We need only the one constructor, because we will add default values.
robot.h
Robot( int x=0, int y=0, float theta=0);
robot.cpp
Robot::Robot( int x, int y, float theta ) {
position[0] = x;
position[1] = y;
directionAngle = theta;
}
main.cpp
There was no need to change anything in main from before. All of the various forms of constructors was captured in the one constructor with default arguments.
int main() {
Robot rosyRobot;
Robot c3poRobot(100,100);
Robot halRobot(3.14);
Robot eveRobot(-100,-100,-3.14/4);
rosyRobot.display();
c3poRobot.display();
halRobot.display();
eveRobot.display();
}
And it comes out like this ...
Pos [0 0]. angle 0
Pos [100 100]. angle 0
Pos [3 0]. angle 0
Pos [-100 -100]. angle -0.785
OOPS. What happened to hal? We specified an angle of 3.14, but that didn't work. Can you explain that?
#### Position is awkward and prone to error. Let's fix that with a class definition.
struct Position {
int x;
int y;
};
But now we have to change all of our code. Too bad we didn't think about this change before we started!