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.
Related
I'm trying to code a simple DirectX11 engine but I keep getting this strange error and I can't find the problem: I define a Terrain class and a Mesh class and #include the Mesh class in the Terrain class:
the Terrain class definition:
// Terrain.h
#pragma once
#include "Noise.h"
#include "Mesh.h"
class Terrain
{
public:
Terrain(float width, float depth, int numVerticesW, int numVerticesD);
~Terrain();
float GetHeight(float x, float z);
void Draw();
private:
Mesh mMesh; // I get the error on this line
Noise mNoiseGenerator;
std::vector<float> mHeights;
void CreateTerrain(float width, float depth, int numVerticesW, int numVerticesD);
float ComputeHeight(float x, float z, float startFrequency, float startAmplitude, float persistence, int octaves);
};
and the Mesh class definition:
// Mesh.h
#pragma once
#include <d3d11.h>
#include <vector>
#include "Game.h"
class Mesh
{
public:
Mesh();
~Mesh();
template <typename T, unsigned int N>
void LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic = false);
void LoadIndexBuffer(std::vector<unsigned int> indices);
void SetVertexCount(unsigned int vertexCount);
void Bind();
void Draw();
private:
std::vector<ID3D11Buffer*> mVertexBuffers;
std::vector<unsigned int> mStrides;
ID3D11Buffer *mIndexBuffer;
unsigned int mVertexCount;
};
template <typename T, unsigned int N>
void Mesh::LoadVertexBuffer(T data[][N], unsigned int size, bool dynamic)
{
D3D11_BUFFER_DESC bufferDesc = {};
bufferDesc.Usage = dynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_IMMUTABLE;
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.ByteWidth = sizeof(T[N]) * size;
bufferDesc.CPUAccessFlags = dynamic ? D3D11_CPU_ACCESS_WRITE : 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA bufferData = {};
bufferData.pSysMem = data;
ID3D11Buffer *buffer;
Game::GetInstance()->GetDevice()->CreateBuffer(&bufferDesc, &bufferData, &buffer);
mVertexBuffers.push_back(buffer);
mStrides.push_back(sizeof(T[N]));
}
When I compile the code I get:
Severity Code Description Project File Line Suppression State
Error C3646 'mMesh': unknown override specifier DirectX11 engine 0.3 c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h 14
Severity Code Description Project File Line Suppression State
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int DirectX11 engine 0.3 c:\users\luca\desktop\programming\code\c++\source\visual studio\directx11 engine 0.3\terrain.h 14
I searched the web but most results show missing semicolons or circular inclusion issues but I can't find any.
EDIT
I found the issue but I can't explain why my solution works:
following the inclusion tree:
Terrain.h --> Mesh.h --> Game.h --> Renderer.h --> Terrain.h
eliminating #include "Terrain.h" (since I just declare Terrain * pointers inside the class) and adding it to Terrain.cpp seems to solve the issue.
So it must be a matter of circular inclusion, but shouldn't I be guarded against that by using header/include guards?
Your problem is that #pragma once only prevents against double inclusion. I.e. it makes the following safe (simplified to make it obvious) :
// Terrain.cpp
#include "Terrain.h"
#include "Terrain.h"
It does not solve circular inclusion, which is far harder to solve automatically. With double inclusion, it's clear which one is first. But a circle has no begin.
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?
Mage/Interface/Context.h
#pragma once
#include <Mage/Interface/Element.h>
#include <Mage/Renderer/RenderingContext.h>
#include <Mage/Renderer/VertexBuffer.h>
#include <glm/glm.hpp>
namespace Mage {
namespace Interface {
class Context {
protected:
RenderingContext* ctx;
VertexBuffer* vbo;
glm::mat4 projection;
Mage::Interface::Frame* uiParent;
public:
Context(RenderingContext* ctx);
~Context();
void render();
Mage::Interface::Frame* createFrame();
};
}
}
Mage/Interface/Element.h
#pragma once
#include <vector>
#include <Mage/Interface/Context.h>
#include <glm/glm.hpp>
namespace Mage {
namespace Interface {
class Element {
protected:
Mage::Interface::Context* ctx;
std::vector<Element*> children;
glm::vec3 position;
float scale;
public:
virtual void draw();
void attach(Element* child) {
this->children.push_back(child);
}
inline glm::vec3 getPosition() {
return this->position;
}
float getScale() {
return this->scale;
}
};
// Frame is an untextured, single colour quad. Frame may contain other
// Elements.
class Frame : public Element {
public:
Frame();
Frame(glm::vec3 pos);
Frame(float width, float height);
Frame(glm::vec3 pos, float width, float height);
};
}
}
This gives me the following errors:
Error C2039 'Context': is not a member of 'Mage::Interface' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C2238 unexpected token(s) preceding ';' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C2143 syntax error: missing ';' before '*' Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int Mage2D c:\users\jesse\documents\visual studio 2015\projects\mage2d\include\mage\interface\element.h 14
When I take out Mage::Interface::Context* ctx, the code compiles fine. I figured I must have missed a semi colon, but I can't see it - it all seems to check out just fine to me.
You have a circular dependency. Element.h includes Context.h and Context.h includes Element.h, that's not going to work.
The way to solve that is to forward-declare types instead of including their headers whenever you can, it'll also reduce compile times.
I have been having issues with Visual Studio 2013. I can't explain why its happening. The compile issue is shown in the pictures below.
I have one class "PhysicsEngine.cpp/h" that use the class "RigidBody.cpp/h" just fine. Once I attempt to use the RigidBody class in my Character class header, it fails to see the RigidBody class identifier. I have included "RigidBody.h" in my file, and even tried prototyping the class. Interesting enough when I delete the "RigidBody.h" header inclusion, it spits out even more errors, leading me to believe it is reading it. Is there something I'm doing wrong?
Here is the output I received as an error:
1>------ Rebuild All started: Project: SideScroller, Configuration: Debug Win32 ------
1> WorldChunkManager.cpp
1> World.cpp
1> Vector.cpp
1>e:(directory)\vector.cpp(41): warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data
1>e:(directory)\vector.cpp(48): warning C4244: 'argument' : conversion from 'double' to 'float', possible loss of data
1> Tile.cpp
1> RigidBody.cpp
1>e:(directory)\character.h(21): error C2146: syntax error : missing ';' before identifier 'pos'
1>e:(directory)\character.h(21): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:(directory)\character.h(21): error C2143: syntax error : missing ';' before '='
1>e:(directory)\character.h(21): error C2238: unexpected token(s) preceding ';'
Here is the code for the RigidBody.h
#ifndef RH
#define RH
#include "Vector.h"
#include "World.h"
#include <cmath>
#include <list>
class RigidBody
{
private:
int id;
float gravityFactor;
float airResistFactor;
float mass;
float elasticity;
Vector pos = Vector(0, 0);
int width;
int height;
Vector velocity = Vector(0, 0);
std::list<Vector>* additiveVelocities;
std::list<Vector>* forces;
public:
RigidBody(int x, int y, int w, int h, float mass, float elasticity, float gravityFactor, float airResistFactor);
~RigidBody();
static int rigidBodyCount;
//Get/Set
int getID();
double getX();
double getY();
float getGravFact();
float getAirFact();
float getMass();
float getElast();
Vector getPos();
Vector getVelocity();
std::list<Vector>* getadditiveVelocities();
std::list<Vector>* getForces();
void setX(double x);
void setY(double y);
void setVelocity(Vector& vec);
void setPos(Vector& vec);
//Interactino Functions
void addForce(Vector force);
void addVelocity(Vector velocity);
};
#endif
Here is the code that will not work (Character.h):
#ifndef CHARACTER_H
#define CHARACTER_H
#include "SDL.h"
#include "Camera.h"
#include "InputManager.h"
#include "Vector.h"
#include "RigidBody.h"
//TEMP DIM
const int CHAR_H = 64;
const int CHAR_W = 12;
class Character
{
private:
double speed;
//Vector pos = Vector(0, 0);
RigidBody pos = RigidBody(0, 0, CHAR_W, CHAR_H, 50, 0, 1, 1);
InputManager* inputPtr;
public:
Character(int x, int y, InputManager* inputPtr);
void getXY(int* dest);
void getChXY(int* dest);
void getCenterXY(int* dest);
//Update
void update(long double last);
bool isFloor();
//Draw
void draw(SDL_Surface* screen, Camera* camPtr);
};
#endif
Let me know if there is anything additional you could need to find the problem!!! I don't want to overload the page with potentially irreverent information. Thank you!
I think the problem with this line isn't that it's failing to find an identifier:
RigidBody pos = RigidBody(0, 0, CHAR_W, CHAR_H, 50, 0, 1, 1);
Rather, it's that you're trying to do an illegal initialization, in a C#-type way. You can't just assign a value to a class member as part of its declaration like that in C++. You need to assign the initial value in the constructor, or in an initializer attached to the constructor.
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)