Creating and initializing classes in C++ - c++

I'm learning to create classes in c++ and I've created a simply Point class. It somehow doesn't compile and I have no clue what went wrong. Please help.
Point.h
#ifndef POINT_H
#define POINT_H
class Point {
private:
float x, y;
public:
//default constructor
Point();
//constructor
Point(float x, float y);
float getX();
float getY();
void print();
};
#endif
Point.cpp
#include "Point.h"
Point::Point(){
x = 0.0;
y = 0.0;
};
Point::Point(float x, float y){
x = x;
y = y;
}
float Point::getX(){
return x;
}
float Point::getY(){
return y;
}
void Point::print(){
cout << "hello" ;
{
main.cpp:
#include <Point.h>
#include <iostream>
int main()
{
Point p(10.0f, 20.0f);
p.print();
return 0;
}
Below is the build message:
||=== Build: Debug in Point (compiler: GNU GCC Compiler) ===|
main.cpp|7|error: no matching function for call to 'Point::Point(float, float)'|
main.cpp|8|error: 'class Point' has no member named 'print'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

You forgot to put Point:: in front of print when defining the body. Also, the x = x in the constructor won't do anything. You need to assign to this->x, and likewise for y.

always use Constructor initialize list if possible
Point::Point()
: x(0.f)
, y(0.f)
{
}
Point::Point(float x, float y)
: x(x)
, y(y)
{
}
return const for both getX() getY()

Related

Incomplete/Undefined type when using nested classes

I have been attempting to make some code, but I am a bit new to c++ and need some help.
I cannot instantiate class Player as a pointer, because it's an "incomplete type" (or undefined type, vs says both). Below are some (simplified, albeit not very) versions of my code:
Entity.h
#pragma once
#include <vector>
class Entity
{
public:
static void init();
class EntityObject;
class Player;
static std::vector<EntityObject*> entities;
};
Entity.cpp
#include "Entity.h"
void Entity::init()
{
entities = std::vector<EntityObject*>();
}
class Entity::EntityObject
{
private:
float velX, velY, x, y;
public:
EntityObject(float xa, float ya) { x = xa; y = ya; }
float getVelX() { return velX; }
float getVelY() { return velY; }
float getX() { return x; }
float getY() { return y; }
};
class Entity::Player : EntityObject
{
public:
Player(float xa, float ya) : EntityObject(xa, ya)
{
printf("Player created");
}
};
Can anyone tell me why
#include "Entity.h"
int main(int argc, char* argv)
{
Entity::init();
Entity::EntityObject* player = new Entity::Player(10.0f, 10.0f);
Entity::entities.push_back(player);
}
gives an incomplete/undefined type?
Thanks.
Edit:
The errors are:
Both errors direct to this line: Entity::EntityObject* player = new Entity::Player(10.0f, 10.0f);
Error (active) E0070 incomplete type is not allowed
Error C2027 use of undefined type 'Entity::Player'
You defined the Entity::Player class in the .cpp file, not in the .h file. Therefore, even though the main() includes the .h file, it does not know about Entity::Player.
Entity::Player is forward declared in Entity.h.
When the compiler compiles your main.cpp module, it does not know anything about this class except that it exists, in particular it has no idea that this class as a constructor taking two float : Player(float xa, float ya)
=> Your issue is related to forward declaring, not nested class.
Read this thread to understand your problem
What are forward declarations in C++?
Read this one to understand what you can and what you can't do with forward declaration
When can I use a forward declaration?

C++ Class Header and Implementation Error

I just recently started messing around with separate class files in c++ and this was my first attempt:
First I made a class header called "ThisClass.h":
//ThisClass.h
#ifndef THISCLASS_H
#define THISCLASS_H
class ThisClass
{
private:
int x;
float y;
public:
ThisClass(int x, float y);
void setValues(int x, float y);
int printX();
float printY();
};
#endif // THISCLASS_H
Then, I implemented my class in a file called "ThisClass.cpp":
//ThisClass.cpp
#include "ThisClass.h"
ThisClass::ThisClass(int x, float y)
{
this->x = x;
this->y = y;
}
void ThisClass::setValues(int x, float y)
{
this->x = x;
this->y = y;
}
int ThisClass::printX()
{
return this->x;
}
float ThisClass::printY()
{
return this->y;
}
Finally, I made a file called "main.cpp" where I used the class:
//main.cpp
#include <iostream>
using namespace std;
int main()
{
ThisClass thing(3, 5.5);
cout << thing.printX() << " " << thing.printY()<< endl;
thing.setValues(5,3.3);
cout << thing.printX() << " " << thing.printY()<< endl;
return 0;
}
I then compiled and ran this program through Code Blocks which uses the MinGW compiler and received the following errors:
In function 'int main()':|
main.cpp|7|error: 'ThisClass' was not declared in this scope|
main.cpp|7|error: expected ';' before 'thing'|
main.cpp|8|error: 'thing' was not declared in this scope|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Am I somehow doing this wrong? Any help would be appreciated.
You forgot to #include "ThisClass.h" in main.cpp.
As already answered that you forgot to put #include "ThisClass.h"in main.cpp.
Just do that and your code will be compiled.
I just want to answer your question -
However, now my console isn't outputting anything even though I have 2 cout calls
Please put a getchar() before return in main function, it will allow you to see your output.

undefined reference to `vtable for ' namespace inheritance undefined reference to `typeinfo for [duplicate]

This question already has answers here:
g++ undefined reference to typeinfo
(18 answers)
Closed 6 years ago.
I have such error messages while compiling my (simple) code:
||=== Build: Release in zad12 (compiler: GNU GCC Compiler) ===|
obj/Release/Section.o||In function `MyFigures::Section::Section()':|
Section.cpp|| undefined reference to `vtable for MyFigures::Figure'|
obj/Release/Section.o||In function `MyFigures::Section::Section(Point, Point)':|
Section.cpp|| undefined reference to `vtable for MyFigures::Figure'|
obj/Release/Section.o||In function `MyFigures::Section::~Section()':|
Section.cpp|| undefined reference to `vtable for MyFigures::Figure'|
Section.cpp|| undefined reference to `vtable for MyFigures::Figure'|
obj/Release/Section.o:(.rodata._ZTIN10MyFigures7SectionE[_ZTIN10MyFigures7SectionE]+0x10)||undefined reference to `typeinfo for MyFigures::Figure'|
||=== Build failed: 5 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
And the code:
#ifndef _FIGURE_H_
#define _FIGURE_H_
namespace MyFigures
{
class Figure
{
public:
Figure(){}
~Figure(){}
virtual void draw();
virtual void move();
virtual void scale(double s);
};
}
#endif
#ifndef _Section_H_
#define _Section_H_
#include "figure.h"
#include "point.h"
#include <exception>
namespace MyFigures
{
class Section : public Figure
{
public:
class badsection : public std::exception
{
public:
const char * what() const throw()
{
return "error";
}
};
Section();
Section(Point start, Point end);
void draw();
void move();
void scale(double s);
~Section();
private:
Point start;
Point end;
};
}
#endif
#include "section.h"
namespace MyFigures
{
Section::Section()
{
}
Section::Section(Point start, Point end)
{
if(start == end)
throw badsection();
}
void Section::draw() {}
void Section::move() {}
void Section::scale(double s) {}
Section::~Section() {}
}
#ifndef _Point_H_
#define _Point_H_
class Point
{
private:
double x,y;
public:
Point();
~Point();
Point(double xx);
Point(double xx, double yy);
Point& operator=(const Point& p);
bool operator==(const Point& p);
};
#endif
#include "point.h"
Point::Point()
{
x = 0;
y = 0;
}
Point::Point(double xx)
{
x = xx;
y = 0;
}
Point::Point(double xx=0, double yy=0)
{
x = xx;
y = yy;
}
Point::~Point()
{
}
Point& Point::operator=(const Point& p)
{
x = p.x;
y = p.y;
return *this;
}
bool Point::operator==(const Point& p)
{
return (x == p.x) && (y == p.y);
}
I tried to make the destructor in Figure class as virtual, but no effect (errors remain).
The problem is, that you have to define every function you declare. That's why the compiler is complaining, you are not defining anything for draw, move or scale.
If you want Figure to be a complete abstract class (which I think this is what you are trying to do), you can set those function to 0, so you don't have to define them, but the derived classes have to implement them.
//Now you don't need to implement them
virtual void draw() = 0;
virtual void move() = 0;
virtual void scale(double) = 0;

Vector of Custom Objects

I am trying to create a vector of custom objects defined in a header file and then initialize them in the actual cpp file. I'm getting the following errors in Visual Studio:
error C2976: 'std::vector' : too few template arguments
error C2065: 'Particle' : undeclared identifier
error C2059: syntax error : '>'
In the code below, the vector is defined in Explosion.h.
Particle.h:
#pragma once
class Particle : public sf::CircleShape {
public:
float speed;
bool alive;
float vx;
float vy;
Particle(float x, float y, float vx, float vy, sf::Color color);
~Particle();
};
Particle.cpp:
#include <SFML/Graphics.hpp>
#include "Particle.h"
Particle::Particle(float x, float y, float vx, float vy, sf::Color color) {
// Inherited
this->setPosition(x, y);
this->setRadius(5);
this->setFillColor(color);
// Player Defined Variables
this->speed = (float).05;
this->alive = true;
this->vx = vx;
this->vy = vy;
}
Particle::~Particle() {
}
Explosion.h:
static const int NUM_PARTICLES = 6;
#pragma once
class Explosion {
public:
std::vector<Particle*> particles;
bool alive;
Explosion();
~Explosion();
};
Explosion.cpp:
#include <SFML/Graphics.hpp>
#include "Particle.h"
#include "Explosion.h"
Explosion::Explosion() {
this->alive = true;
// Add Particles to vector
for (int i = 0; i < NUM_PARTICLES; i++) {
this->particles.push_back(new Particle(0, 0, 0, 0, sf::Color::Red));
}
}
Explosion::~Explosion() {
}
I'm sure there is something fundamentally wrong here since C++ is fairly new to me.
You need to tell Explosion.h what a Particle is.
In this case, Explosion.h is using Particle*, so a forward declartion will suffice.
Explosion.h
class Particle; // forward declaration of Particle
class Explosion {
// ...
};
You could also simply #include "Particle.h, however as your projects increase using forward declarations (instead of direct includes) can significantly reduce your build times.

Overloading difficulty with an extended sprite class. How is this wrong?

So I've been working on a puzzle game using a sprite system I used fine previously and in my past projects have been fine when extending the class, however my code keeps throwing an error of
error C2511:
'Door:: Door(float,float,float,float,float,float,int,CGame *)' :
overloaded member function not found in 'Door'
and I have no idea why as i've checked all the classes in my previous project and how they interface with the rest of the program and it's IDENTICAL but this new class is still erroring out. and the code in my main to create the object throws "no overloaded function in Door takes 8 arguments" out.
Door Class:
Door.h
#pragma once
#include "sprite.h"
class CGame;
class Door :
public CSprite
{
public:
Door(void);
Door(float, float, float, float,float, float, float, int, CGame * p_Game);
void Update(float dt);
~Door(void);
private:
};
Door.CPP
#include "stdafx.h"
#include "Door.h"
#include "Game.h"
Door::Door(void)
{
}
//So this is where i try to make door class extend sprite. but it keeps saying "overloaded member function not found in Door"
//and the other error is "doesnt take 8 args" and to top it off. It says unexpected end of file.
//Uncomment this block and the code in the door bit of the map gen to see what it is doing wrong
Door::Door(float _x, float _y, float _w, float _h, float _vX, float _vY, int _texID, CGame * p_Game) : CSprite(_x, _y, _w, _h, _vX, _vY, _texID, p_Game)
{
m_iType = 4 //sets the type of sprite that this object is.
}
void Door::Update(float dt)
{
}
Door::~Door(void)
{
}
and this is the sprite class i am extending (just the relevant parts)
Sprite.h
#pragma once
class CGame;
class CSprite
{
public:
float m_fX; //the position of the centre of the sprite
float m_fY;
float m_fW; //width of the sprite in arbitrary units
float m_fH; //height of the sprite in arbitrary units
float m_fvX;
float m_fvY;
int m_iTextureID; //which of the preloaded textures to use
float m_fR; //red component between 0 and 1
float m_fG; //green component between 0 and 1
float m_fB; //blue component between 0 and 1
float m_fA; //alpha value 0-1
int m_iType;
CGame * m_pGame;
public:
CSprite();
CSprite(float x, float y, float w, float h,float vX,float vY, int textureID ,CGame * p_Game);
bool bIsCollidingWith( CSprite * othersprite_);
bool markedForDelete;
//This new constructor is added to the Csprite.h header file.
float getX() { return m_fX; }
float getY() { return m_fY; }
virtual bool TagForDeletion();
virtual int GetSpriteType();
virtual ~CSprite();
virtual void Render();
virtual void Update(float dt);
};
Sprite.cpp
#include "StdAfx.h"
#include <gl.h>
#include <glut.h>
#include <glaux.h>
#include "main.h"
#include "sprite.h"
#include "Game.h"
CSprite::CSprite( )
{
m_fX=0.0f;
m_fY=0.0f;
m_fW=1.0f;
m_fH=1.0f;
m_fvX=0.0f;
m_fvY=0.0f;
markedForDelete=false;
m_fR=m_fG=m_fB=m_fA=1.0;
m_iTextureID=0;
}
CSprite::CSprite(float x_, float y_, float w_, float h_,float vX_,float vY_, int textureID_, CGame * p_Game)
{
m_iType = 1;
m_fX=x_;
m_fY=y_;
m_fW=w_;
m_fH=h_;
m_fvX=vX_;
m_fvY=vY_;
m_fR=m_fG=m_fB=m_fA=1.0;
m_iTextureID=textureID_;
m_pGame = p_Game;
markedForDelete=false;
}
CSprite::~CSprite(void)
{
}
Implementation in the game class uses the parameters extended from Sprite to create the object
p_Door[m_iSpritesLoaded++]=new Door(uiRow,4.58 -uiCol,1,1,0,0,4,this);
You miscounted your floats.
Declaration
Door(float, float, float, float,float, float, float, int, CGame * p_Game);
// 1 2 3 4 5 6 7
Definition
Door::Door(float _x, float _y, float _w, float _h, float _vX, float _vY, int _texID, CGame * p_Game)
// 1 2 3 4 5 6
: CSprite(_x, _y, _w, _h, _vX, _vY, _texID, p_Game)
Usage
p_Door[m_iSpritesLoaded++]=new Door(uiRow,4.58 -uiCol,1,1,0,0,4,this);
// 1 2 3 4 5 6
(Did you really need Stack Overflow for this?!)
Looks like your Door constructor has one extra float parameter. The declaration has 7 floats whereas the definition in Door.cpp has 6.
In Door.h the constructor has 9 arguments
Door(float, float, float, float,float, float, float, int, CGame * p_Game);
while in the Door.cpp the definition of the constructor has only 8 elements, that is one float is missing.
Solution:
add one argument to the definition of the constructor
CSprite::CSprite(float x_, float y_, float w_, float h_,float vX_,float vY_, int textureID_, CGame * p_Game)