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.
Related
In C++, it is sometimes considered good practice to declare your classes in a header file and define all the methods in a cpp file. I understand this, but a consequence of this seems to be that instead of having all of the class methods tabbed-in inside curly braces, they are just out in the open in the cpp file. Is there any way to group the methods of a class together in the cpp file while still declaring them in a header file? I like being able to collapse things in my IDE... I'd just get over it, but it's been a while since I've coded anything in C++ and I'm wondering if there's a way to do it that I just forgot about.
To be clear what I mean, here's an example:
test.h:
class Testing {
public:
Testing(int x);
void print();
int x;
};
test.cpp:
#include <iostream>
#include "test.h"
using namespace std;
// class Testing {
// public:
// Testing(int x){
// this->x = x;
// }
// void print(){
// cout << this->x << endl;
// }
// };
Testing::Testing(int x){
this-> x = x;
}
void Testing::print(){
cout << this->x;
}
int main(){
Testing t(100);
t.print();
}
I'd like to do what is commented above in test.cpp instead, but that doesn't work, right? (I think it'd be like declaring a new class distinct from the one in the header file?)
You could do this:
== h.h ==
namespace H_DEFS {
class H {
public:
int A();
int B();
};
}
using namespace H_DEFS;
== h.cpp file ==
#include "h.h"
namespace H_DEFS {
int H::A() { return 4;};
int H::B() { return 5;};
}
== main.cpp ==
#include "h.h"
int main() {
return H().A() + H().B();
}
but it's a weird idiom for other programmers to read just for the benefit of your IDE.
Im having an issue getting my variable from my original class to print in another class method
Quick example of my issue:
say the variable was declared here in the test.h file:
class player{
private:
int x = 10;
void setX(); //method for setting X from user input
int getX(); //Method for retrieving variable
}
Then in another class method where i want to print X
class inTheWoods{
public:
printInfo();
}
test.cpp file:
void player::setX(){
cout << "Set X to a number:" << endl;
cin >> x
}
int player::getX(){
return x;
}
int inTheWoods::printInfo(){
player playerObj; //Player object to access methods in player class
cout << playerObj.getX();
}
main.cpp:
int main(){
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Whenever I run my program that resembles this problem the int does not display correctly and throws me a strange negative number. I hope this isnt too much code and that I documented everything correctly
If you want the classes to be in a separate files, it should still work:
Main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Player.h
#pragma once
#include <iostream>
class Player
{
int x = 10;
void setX();
public:
int getX();
};
Player.cpp
#include "Player.h"
void Player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> x;
}
int Player::getX()
{
return x;
}
inTheWoods.h
//#pragma once
#include "Player.h"
#include <iostream>
class inTheWoods
{
public:
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
void inTheWoods::printInfo()
{
Player playerObj; //Player object to access methods in player class
std::cout << playerObj.getX();
}
#pragma once is a preprocessor that prevents multiple includes, in case you didn't know. You can choose to skip it (Visual Studio auto-generated the file with the line).
In summary, these are the changes I needed to make from your implementation:
Move declaration of getX() from private to public.
Add semicolons to the end of every class.
Add a return type to printInfo(). If you don't want a function to return anything, the return type is void. Unless you care declaring a constructor, which doesn't seem to be the case here.
Here is the working one. It's always a good practice to give a constructor, in order to create an instance with some default values. the following code will work hopefully according to your requirements:
main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
player.h
#pragma once
class player
{
private:
int m_x;
public:
player();
player(const int& x);
void setX(); //method for setting X from user input
const int& getX()const; //Method for retrieving variable
};
player.cpp
#include "player.h"
#include <iostream>
player::player() // defualt constructor
:m_x(0) {}
player::player(const int& x)
:m_x(x) {} // parameterised
void player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> m_x;
}
const int& player::getX()const
{
return m_x;
}
inTheWoods.h
#pragma once
class inTheWoods
{
public:
inTheWoods();
~inTheWoods();
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
#include "player.h"
#include <iostream>
inTheWoods::inTheWoods() {}
inTheWoods::~inTheWoods() {}
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
player playerObj2(10); // will beinitialized with 10
std::cout << playerObj.getX() <<std::endl;
std::cout << playerObj2.getX() <<std::endl;
}
Edit: Well if you wanna allow the user to set values your printInfo() must be as follows:
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
playerObj.setX();
std::cout << playerObj.getX() <<std::endl;
}
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
I have a little problem, i probably included the class files wrongly, since i can't acces members of the enemy class. What am i doing wrong?
my cpp for class
#include "classes.h"
class Enemy
{
bool alive;
double posX,posY;
int enemyNum;
int animframe;
public:
Enemy(int col,int row)
{
animframe = rand() % 2;
posX = col*50;
posY = row*50;
}
Enemy()
{
}
void destroy()
{
alive = 0;
}
void setposX(double x)
{x = posX;}
void setposY(double y)
{y = posY;}
};
my header for class:
class Enemy;
my main:
#include "classes.h"
Enemy alien;
int main()
{
alien. // this is where intelisense tells me there are no members
}
Your main file will only see what you wrote in the header, which is that Enemy is a class. Normally, you'd declare your whole class with fields and method signatures in the header files, and provide implementations in the .cpp file.
classes.h:
#ifndef _CLASSES_H_
#define _CLASSES_H_
class Enemy
{
bool alive;
double posX,posY;
int enemyNum;
int animframe;
public:
Enemy(int col,int row);
Enemy();
void destroy();
void setposX(double x);
void setposY(double y);
};
#endif
classes.cpp:
#include "classes.h"
//....
void Enemy::destroy(){
//....
}
//....
In addition to Vlad's answer, your file with main doesn't know anything about the Enemy class, other than that it exists.
In general, the class declarations goes in the header file, and the function definitions go in another.
Consider splitting the files like:
classes.h:
#ifndef CLASSES_H
#define CLASSES_H
class Enemy
{
private:
bool alive;
double posX,posY;
int enemyNum;
int animframe;
public:
Enemy(int col,int row);
Enemy();
void destroy();
void setposX(double x);
void setposY(double y);
};
#endif//CLASSES_H
Note the "include guards" which prevent the same file from being included more than once. Good practice to use on header files, or else you get annoying compilation errors.
classes.cpp:
#include "classes.h"
Enemy::Enemy(int col,int row)
{
animframe = rand() % 2;
posX = col*50;
posY = row*50;
}
Enemy::Enemy()
{
}
void Enemy::destroy()
{
alive = 0;
}
void Enemy::setposX(double x) {x = posX;}
void Enemy::setposY(double y) {y = posY;}
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(){
}