So I am trying to forward declare a class in my C++ project and then create it in main.
So I have player_obj.cpp which contains the class, classes.h which forward declares the class, and main.cpp which uses it.
classes.h
#ifndef CLASSES_H
#define CLASSES_H
class player_class
{
public:
int x;
int y;
char sprite;
int xprevious;
int yprevious;
private:
bool active;
public:
void update_xy();
player_class(int _x, int _y, char _sprite);
void step();
void destroy();
};
#endif
main.cpp
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
player_class player_obj (5,5,'#');
cout << player_obj.x << ", " << player_obj.y << endl;
return 0;
}
and player_obj.cpp
#include <iostream>
#include <Windows.h>
using namespace std;
class player_class
{
public:
//Coordinates
int x;
int y;
//Sprite
char sprite;
//Previous coordinates
int xprevious;
int yprevious;
//Not everyone can set the activity
private:
//Active
bool active;
//Update xprevious and yprevious - Called by the step event
void update_xy()
{
xprevious = x;
yprevious = y;
}
//All functions public
public:
//Create event/Constructer
player_class(int _x, int _y, char _sprite)
{
//Set default variables
x = _x;
y = _y;
sprite = _sprite;
xprevious = x;
yprevious = y;
active = true;
}
//Step event
void step()
{
//Update old xprevious and yprevious
update_xy();
//Do other stuff here
}
//Drestroy event
void destroy()
{
active = false;
}
};
I thought that would work out all right but when I compile and run it I get:
main.cpp:(.text+0x2c): undefined reference to`player_class::player_class(int, int, char)'
I've done some research, but I can't seem to fix this issue.
I greatly appreciate any help!
Well you're sort of close, what you have in your header is indeed a class declaration (not a forward declaration mind you).
The problem is you never defined it. What you have in player_obj.cpp is an abomination of class redefinition, but you already have your class declared. Just include the header file and define the functions one by one and you're done!
#include "classes.h"
player_class::player_class(int _x, int _y, char _sprite)
{
//Set default variables
x = _x;
y = _y;
sprite = _sprite;
xprevious = x;
yprevious = y;
active = true;
}
// and so on
If you're serious about learning modern C++ though, a few notes:
#pragma once is the modern way of guarding header files. Don't use those #ifdef..#endif constructs.
generally speaking, don't name anything starting with underscores. Especially not parameters visible as part of your public contract.
you have class initializers for a reason, use them! You don't need half a screen of copy pasting variables in your constructors.
You dont want a forward declaration. You want a declaration. It is a classical case of declaring a class in a header file and defining its functions in a cpp file. Then including the header where-ever you want to use your class
You only need forward declarations when you want to use a pointer to that class as a parameter to a function or a member variable somewhere but the definition of that class is not available yet.
Note that when you forward declare a class, you cannot use this class's member variables or functions in that header
-regards
Gautam
Related
I am trying to figure out how the C++ key word "this" works. I followed the codes below, but it does not pass and show the error of "C4430: Missing type specifier, int assumed"
#include <iostream>
#include <string>
void PrintEntity(const Entity& e);
class Entity
{
public:
int x, y;
Entity(int x, int y)
{
this->x = x;
this->y = y;
PrintEntity(*this);
}
};
void PrintEntity(const Entity& e)
{
std::cout << "Entity" << std::endl;
}
int main()
{
return 0;
}
I reviewed other similar questions, the solutions include adding "return 0" to the Main function or circular dependency. But I don't think these solutions apply for me. Please help me solve it, thanks!
You are trying to declare PrintEntity's interface before the type of its one parameter is even declared, Entity.
You have to declare Entity first (without defining it, as its definition does use PrintEntity), before you use it in PrintEntity's declaration. You can do this by adding the line class Entity; before PrintEntity's declaration.
Once they're both declared, then the definitions are ok.
Important
As suggested in the comments, one more way to have the code compile/work, is to use a so called elaborated type specifier. With reference to the specific example, it is enough to change
void PrintEntity(const Entity& e);
to
void PrintEntity(const class Entity& e);
Keep in mind that you don't have to define everything in the class all at once. Another option is to defer the definition of the constructor to after the definition of PrintEntity:
#include <iostream>
#include <string>
class Entity
{
public:
int x, y;
Entity(int x, int y);
};
void PrintEntity(const Entity& e)
{
std::cout << "Entity" << std::endl;
}
Entity::Entity(int x, int y)
{
this->x = x;
this->y = y;
PrintEntity(*this);
}
In this case you can get rid of the declaration of PrintEntity before the definition of the Entity class because you don't need it yet.
I am new to c++ and am stuck on the syntax of declaring classes.
From what I have gathered you should store all declarations in a header file, I'll call it declarations.h;
#pragma once
void incptr(int* value);
void incref(int& value);
class Player
{
public:
int x, y;
int speed;
void Move(int xa, int ya)
{
x += xa * speed;
y += ya * speed;
}
void printinfo()
{
std::cout << x << y << speed << std::endl;
}
};
Now Player is a class which I want to store in a cpp file called functions.cpp
I want to move the above Player class into the below file functions.cpp
#include "common.h"
void incptr(int* value)
{
(*value)++;
}
void incref(int& value)
{
value++;
}
common.h contains;
#pragma once
#include <iostream>
#include <string>
#include "declarations.h"
What I think is happening is when i write the Player class in the header file, its being declared in that file, well, already there. If i move the Player class into functions.cpp I need to leave a declaration. I'm not sure what the compiler expects as a declaration when it comes to classes.
I have tried;
class Player();
functions::Player();
void Player::Move(int xa, int ya);
Also a few other variations but these make the most sense to me.
Sorry if this is a bit messy, still trying to get a hold on the language. Thanks in advance for you help!
Edit: Sorry I missed the main function;
#include "common.h"
int main()
{
Player player = Player();
player.x = 5;
player.y = 6;
player.speed = 2;
player.Move(5, 5);
player.printinfo();
std::cin.get();
}
A declaration for a class is just as simple as
class Player; // Note there are no parentheses here.
This form is most commonly used when you have circular dependencies between two classes. It is more common to define a class in a header file but put the definitions of member functions in a .cpp file. For your purposes a we can make a header file named player.h:
class Player
{
public:
int x, y;
int speed;
void Move(int xa, int ya);
void printinfo();
};
Note that this declaration does not contain the bodies of the member functions because these are really definitions. You can then put the function definitions in another file. Call it player.cpp:
void Player::Move(int xa, int ya)
{
x += xa * speed;
y += ya * speed;
}
void Player::printinfo()
{
std::cout << x << y << speed << std::endl;
}
Note how we have to now specify that each of these functions is a member of the Player class with the Player:: syntax.
Now assuming you also have a main.cpp file with your main() function, you can compile your code like this:
g++ main.cpp player.cpp
For this simple example, you will be fine defining your functions inside of the class declaration. Note that this makes the functions "inline" which is another topic that you should read about.
First post so take it easy on me :). I don't think I really need to put up any actual code for this, but let me know if I'm wrong. This is for a homework assignment in my college programming class. I am confused as to how to properly use my #include statements. Here is my file structure:
Header Files-->
header.h (Main header file, contains #include for various libraries, declares namespace, and provides my name and class info)
room.h (Blueprint for the room class)
ship.h (Blueprint for the ship class)
Source Files-->
main.cpp (Main Program)
functions.cpp (Functions for the main program)
room.cpp (Functions in the Room class)
ship.cpp (Functions in the Ship class)
Basically, my first instinct was to " #include "header.h" " in room.h, ship.h, main.cpp, and functions.cpp. Then " #include "ship.h" in ship.cpp, and " #include room.h " in room.cpp. However I began getting errors up the wazoo. I was having a similar problem during class but I had my teacher there to sort it out and I'm not exactly sure how we did it, and I also know that tons of errors usually indicates an include error.
Its annoying because I had it working somehow before I added the functions.cpp, but I really want to keep main.cpp pretty clean, so I would rather have functions in a separate file.
What is the best pattern for includes in a situation like this?
EDIT: I'll post my 3 header files
header.h
/*
Author: *********
Class : **********
Assignment : Programming Assignment 2
Description :
This program will construct a ship for the user. It accepts input from a file
containing information on various rooms. It will then check the rooms
validity and add it to the ship if it's valid. Once all of the rooms have been added,
the program will determine if the entire ship is valid and let the user know.
Certification of Authenticity :
I certify that this is entirely my own work, except where I have given
fully - documented references to the work of others.I understand the
definition and consequences of plagiarism and acknowledge that the assessor
of this assignment may, for the purpose of assessing this assignment :
-Reproduce this assignment and provide a copy to another member of
academic staff; and / or
- Communicate a copy of this assignment to a plagiarism checking
service(which may then retain a copy of this assignment on its
database for the purpose of future plagiarism checking)
*/
#ifndef header_h
#define header_h
#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
#endif
room.h
#ifndef room_h
#define room_h
#include "header.h"
enum RoomType
{
UNKNOWN = -1,
BAY,
LATRINE,
CABIN,
BRIDGE,
NUM_ROOM_TYPES
};
const string ROOM_STRINGS[NUM_ROOM_TYPES] = { "Bay",
"Latrine",
"Cabin",
"Bridge"
};
class Room
{
public:
//default constructor
Room();
//constructor
Room( RoomType type, int width, int breadth, int height );
//destructor
~Room(){};
//accessors
inline RoomType getType() const { return mType; };
inline int getHeight() const { return mHeight; };
inline int getWidth() const { return mWidth; };
inline int getBreadth() const { return mBreadth; };
inline int getVolume() const { return getWidth() * getBreadth() * getHeight(); }; //currently unused
inline string getRoomName(){ return ROOM_STRINGS[mType]; };
string getDescription();
//mutators
void setType(RoomType type) {mType = type; };
void setHeight(int height) {mHeight = height; };
void setWidth(int width) {mWidth = width; };
void setBreadth(int breadth) {mBreadth = breadth; };
private:
//type of room
RoomType mType;
//floor dimensions - in feet
int mWidth;
int mBreadth;
//ceiling height - in feet
int mHeight;
};
#endif
ship.h
#ifndef ship_h
#define ship_h
#include "header.h"
const int MAX_BAY = 4;
const int MAX_LATRINE = 15;
const int MAX_BRIDGE = 1;
const int MAX_CABIN = 25;
const int MIN_BAY = 1;
const int MIN_LATRINE = 1;
const int MIN_BRIDGE = 1;
const int MIN_CABIN = 0;
const int MIN_ROOM_HEIGHT = 7;
const int MIN_ROOM_AREA = 20;
class Ship{
public:
Ship();
bool addRoom(const Room& theRoom);
string getDescription();
//Accessors
int getNumBays(){ return bayTotal; };
int getNumLatrines(){ return latrineTotal; };
int getNumBridges(){ return bridgeTotal; };
int getNumCabins(){ return cabinTotal; };
int getTotalSquareFootage(){ return totalSquareFootage; };
private:
Room Bay[MAX_BAY];
Room Latrine[MAX_LATRINE];
Room Bridge[MAX_BRIDGE];
Room Cabin[MAX_CABIN];
int bayTotal;
int latrineTotal;
int bridgeTotal;
int cabinTotal;
int totalSquareFootage;
bool isShipValid();
void addSquareFootage(float);
};
#endif
What kind of errors? Your issue might be including the same header more than once.
Try adding this to each header:
#ifndef ROOM_H
#define ROOM_H
... code ...
#endif
To be clear the 'ROOM_H' above needs to be unique to each header.
If you use #include "room.h" in different cpp files then you probably get a linker error because this below here is not a type declaration.
const string ROOM_STRINGS[NUM_ROOM_TYPES] = { "Bay",
"Latrine",
"Cabin",
"Bridge"
};
You are creating and allocating a variable with name ROOM_STRINGS. By declaring it in different cpp files you will have multiple copies of the same global variable which is an error. You could replace it with
static const string ROOM_STRINGS[NUM_ROOM_TYPES] = { "Bay",
"Latrine",
"Cabin",
"Bridge"
};
You will still have multiple copies but each cpp file will have its own private copy. A better solution is to move this declaration into the room cpp file together with the code of the getRoomName.
Or you could declare ROOM_STRINGS as extern in the header and then you still need to add the variable allocation in a cpp file.
I need to have two alternate classes with the same name, that I can switch between each other by simply changing which class is included in main.
For example;
Mode_1.h
class Draw{
private:
// private stuff
public:
void Render(int x, char y);
};
Mode_2.h
class Draw{
private:
// private stuff
public:
void Render(int x, char y);
};
main.cpp
#include "Mode_1.h"
int main(){
Draw D;
int x = 2;
char y = 'x';
D.Render(x, y);
}
Currently I'm having to comment out the .h and .cpp files I'm not using to avoid the "first defined here" error. What I want is that all I have to do to switch between them is change
#include "Mode_1.h"
to
#include "Mode_2.h"
You should put them in different namespaces:
namespace Mode2
{
class Draw{
private:
// private stuff
public:
Draw(int x, char y);
};
}
In main you can then select the namespace you want to use:
#include "Mode_1.h"
#include "Mode_2.h"
using namespace Mode2;
int main()
{
Draw D;
int x = 2;
char y = 'x';
D.Draw(x, y);
return 0;
}
You may try like this:
#ifdef MODE1
#include "Mode_1.h"
#else
#include "Mode_2.h"
#endif
int main(){
Draw D;
int x = 2;
char y = 'x';
Draw(x, y);
}
And compile this source file with -DMODE1 or none depending on you wish to include Mode_1.h or Mode_2.h
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.
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.
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.
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.
Add in motor.cpp
Motor::Motor(){
}