I have a class RenderMachine which includes RenderObject and vice versa. I know there have been tons of questions about this error, but the solution for this doesn't do anything.
They say the error is mostly because a include-loop but I don't have one because in the RenderObject header I only allocate memory for a pointer to RenderMachine and vice versa.
RenderObject.h
#pragma once
#include "RenderMachine.h"
class RenderObject
{
public:
RenderObject(RenderMachine* rm){}
};
RenderMachine.h
#pragma once
#include "RenderObject.h"
class RenderMachine
{
public:
void add(RenderObject* renderObject);
};
The exact error is
error: expected ‘)’ before ‘*’ token
RenderObject(RenderMachine* rm)
^
Edit:
#include "RenderMachine.h"
class RenderMachine;
class RenderObject : public sf::Drawable
{
private:
int renderId;
public:
RenderObject(RenderMachine* rm){ (*rm).add(*this); }
int getRenderId() const { return renderId; }
#include "RenderObject.h"
class RenderMachine
{
std::vector< std::vector<sf::Drawable*> > renderVector;
public:
void add(RenderObject* renderObject);
And RenderMachine.cpp
#include "RenderMachine.h"
void RenderMachine::add(RenderObject* renderObject)
{
renderVector[(*renderObject).getRenderId()].push_back(renderObject);
}
Your call to add in the constructor of RenderObject should be done when RenderMachine is known (when it's a complete type). This goes for all calls to an object of the other type that you now have in your header files. Like this:
// RenderObject.h
class RenderMachine;
class RenderObject {
public:
RenderObject(RenderMachine* rm);
};
// RenderMachine.h
class RenderObject;
class RenderMachine {
public:
void add(RenderObject* renderObject);
};
// RenderObject.cpp
RenderObject::RenderObject(RenderMachine* rm) {
rm->add(this);
}
// RenderMachine.cpp
void RenderMachine::add(RenderObject* ro) {
}
You have a classic chicken-and-egg problem. The compiler cannot parse one header without first parsing the other header, because the classes in the headers refer to each other.
The solution is to use a forward declaration like this:
#include "RenderMachine.h"
class RenderMachine; // forward declaration
class RenderObject
{
public:
RenderObject(RenderMachine* rm){}
};
Related
I'm getting some compiling errors when creating constructors for my derived image classes while using PImpl Idiom and Curiously Recurring Template Pattern. The base class for image class implementations uses CRTP (Curiously Recurring Template Pattern) to enforce static dispatch instead of layering on another virtual call. Please tell me what I'm doing wrong. Please see the comments for where the errors occur
// Error: no matching constructor for initialization of 'jpeg_image::impl' [clang-diagnostic-error]
// Error: field has incomplete type 'jpeg_image::impl' [clang-diagnostic-error]
image.hpp
#include <memory>
#include <vector>
namespace image_wrapper {
class image {
public:
//ToDo: declare pure virtual functions
};
class jpeg_image final : public image {
class impl;
std::unique_ptr<impl> _impl;
public:
// Destructor and constructor for reading from a buffer of encoded_bytes
~jpeg_image();
jpeg_image(std::vector<uint8_t> encoded_bytes);
};
} //namespace image_wrapper
image.cpp
#include "image.hpp"
#include <boost/gil.hpp>
#include <functional>
namespace image_wrapper {
namespace {
template <class Derived>
class impl_base {
public:
// ToDo: implement base class functions
protected:
// Constructor
explicit impl_base(std::vector<uint8_t> encoded_bytes) :
_unencoded_image{ std::bind(&impl_base<Derived>::initialize_unencoded_image, this) }, _encoded_bytes{ encoded_bytes }
{
}
private:
boost::gil::rgb8_image_t initialize_unencoded_image() { return static_cast<Derived&>(*this).decode_bytes(); }
boost::gil::rgb8_image_t _unencoded_image;
std::vector<uint8_t> _encoded_bytes;
};
} // namespace
/*
* JPEG Class Definitions
*/
class jpeg_image::impl : public impl_base<jpeg_image::impl> {
public:
// Error: field has incomplete type 'jpeg_image::impl'
jpeg_image::impl(std::vector<uint8_t> encoded_bytes) : impl_base<jpeg_image::impl>(encoded_bytes) {}
boost::gil::rgb8_image_t decode_bytes()
{
// ToDo: implement decode_bytes()
}
};
// Error: no matching constructor for initialization of 'jpeg_image::impl' [clang-diagnostic-error]
jpeg_image::jpeg_image(std::vector<uint8_t> encoded_bytes) : _impl(new jpeg_image::impl(encoded_bytes)) {}
// Jpeg Image Destructor
jpeg_image::~jpeg_image() = default;
} // namespace image_wrapper
I have two classes: SessionCardsMode and SetOfCards. SessionCardsMode takes in its constructor pointer to object of SetOfCards. When I try to create dynamically new SessionCardsMode object in SetOfCards method initializing it with this pointer I get information: "Cannot initialize type 'SessionCardsMode' with rvalue of type 'SetOfCards*'". It looks like I haven't proper constructor, but I have provided it. I don't know why it doesn't work. The problem is in SetOfCards::getSessionCards method in the first line of it. I've found that if I try to create the same object in body of class SessionCardsMode using identical statement everything works fine, but if I try to make it out of class I get the error.
//////////////////////////////SesionCardsMode.h
#pragma once
#include "Card.h"
#include "SetOfCards.h"
class SessionCardsMode
{
protected:
SetOfCards* m_setData;
std::forward_list<Card*> m_sessionSet;
public:
explicit SessionCardsMode(SetOfCards* set) : m_setData(set) {};
virtual Card* getCard();
//allows making combination of set setup by mixing classes that derives
//from ModeOfSet
void addAndShuffle(const SessionCardsMode* mode);
};
///////////////////////////////SetOfCards.h
#pragma once
#include "Card.h"
#include "SessionCardsMode.h"
class SetOfCards
{
private:
std::vector<Card> m_cardSet;
std::string m_setName;
public:
SetOfCards()=default;
explicit SetOfCards(std::string setName);
template<typename Iter>
SetOfCards(Iter begin, Iter end, std::string setName);
SessionCardsMode* getSessionCards(std::vector<CreatorAndInitVal> creators);
};
////////////////////////////////////////SetOfCards.cpp
#include "SetOfCards.h"
SessionCardsMode* SetOfCards::getSessionCards(
std::vector<CreatorAndInitVal> m_sessionCardsCreators)
{
SessionCardsMode* sessionCards=new SessionCardsMode(this); // error here
return sessionCards;
}
I don't understand why you don't get an error when you declare the constructor of SessionCardsMode (when you are compiling SetOfCards.cpp) - as far as I can see, at that point, SetOfCards is not defined.
Anyway, the solution to your problem is not to #include any of the headers in other headers, but to declare (not define) the other classes. So:
//////////////////////////////SesionCardsMode.h
#pragma once
class Card;
class SetOfCards;
class SessionCardsMode
{
protected:
SetOfCards* m_setData;
std::forward_list<Card*> m_sessionSet;
public:
explicit SessionCardsMode(SetOfCards* set) : m_setData(set) {};
...
};
///////////////////////////////SetOfCards.h
#pragma once
class Card;
class SessionCardsMode;
#include <vector> // You need this
#include <string>
class SetOfCards
{
private:
std::vector<Card> m_cardSet;
std::string m_setName;
public:
SetOfCards()=default;
explicit SetOfCards(std::string setName);
...
};
////////////////////////////////////////SetOfCards.cpp
#include "SetOfCards.h" // This should always be first
#include "..." // You'll probably need some more here.
SessionCardsMode* SetOfCards::getSessionCards(
std::vector<CreatorAndInitVal> m_sessionCardsCreators)
{
SessionCardsMode* sessionCards=new SessionCardsMode(this); // Error should be fixed
return sessionCards;
}
I'm running into a strange problem using forwards declarations. Here is the code:
The Torse class, torse.hpp
#ifndef _TORSE_
#define _TORSE_
class Animation;
enum frame_type;
class Torse : public Renderable
{
public:
const glm::vec3& getCurrentRotation(frame_type);
};
#endif
in torse.cpp:
#include "torse.hpp"
#include "animation.hpp"
const glm::vec3& Torse::getCurrentRotation(frame_type t)
{...}
Now in Animation class, animation.hpp
#ifndef __ANIMATION_H__
#define __ANIMATION_H__
class torse;
class frame {...};
class Animation {
public:
void generateInterpolation(torse& me);
};
#endif
in animation.cpp:
#include "animation.hpp"
#include "torse.hpp"
void Animation::generateInterpolation(torse &me)
{
...
f1.rot[j] = me.getCurrentRotation(f1.type)[j];
...
}
As you can see I'm sharing the enum frame_type and the classes Anmation and Torse But I feel Like I'm doing it right, as in animation.cpp it should know how torse is thanks to torse.hpp...
clang gives me this error:
src/animation.cpp:19:43: error: member access into incomplete type 'torse'
f1.rot[j] = me.getCurrentRotation(f1.type)[j];
^
Anyone have a clue?
You defined a type Torse, but clang complains about a type named torse.
Fix your case.
I'm writing some exception classes in c++ that inherit from a base class and I can't figure out why it won't compile. Any help would be appreciated.
Base Class:
RandomAccessFileException.h
#ifndef RANDOMACCESSFILEEXCEPTION_H
#define RANDOMACCESSFILEEXCEPTION_H
class RandomAcessFileException
{
public:
RandomAcessFileException();
virtual const char* getMessage() = 0;
protected:
char m_message[100];
};
#endif
Derived Class:
RandomAccessFileNotFoundException.h
#ifndef RANDOMACCESSFILENOTFOUNDEXCEPTION_H
#define RANDOMACCESSFILENOTFOUNDEXCEPTION_H
#include "RandomAccessFileException.h"
class RandomAccessFileNotFoundException : public RandomAccessFileException
{
public:
RandomAccessFileNotFoundException(const char* p_filename);
const char* getMessage();
};
#endif
RandomAccessFileNotFoundException.cpp
#include <cstring>
#include "RandomAccessFileException.h"
#include "RandomAccessFileNotFoundException.h"
RandomAccessFileNotFoundException::RandomAccessFileNotFoundException(const char* p_filename)
{
strcat(m_message, "RandomAccessFileNotFoundException: File: ");
strcat(m_message, p_filename);
}
const char* RandomAccessFileNotFoundException::getMessage()
{
return m_message;
}
g++ says:
In file included from RandomAccessFileNotFoundException.cpp:4:0:
RandomAccessFileNotFoundException.h:13:1: error: expected class-name before ‘{’ token
RandomAccessFileNotFoundException.cpp: In constructor ‘RandomAccessFileNotFoundException::RandomAccessFileNotFoundException(const char*)’:
RandomAccessFileNotFoundException.cpp:8:12: error: ‘m_message’ was not declared in this scope
RandomAccessFileNotFoundException.cpp: In member function ‘const char* RandomAccessFileNotFoundException::getMessage()’:
RandomAccessFileNotFoundException.cpp:14:12: error: ‘m_message’ was not declared in this scope
First problem:
You have to:
#include "RandomAccessFileException.h"
In your RandomAccessFileNotFoundException.h header file, since it contains the definition of the base class of RandomAccessFileNotFoundException (i.e. RandomAccessFileException).
So to sum it up, your header file RandomAccessFileNotFoundException.h header should be:
#ifndef RANDOMACCESSFILENOTFOUNDEXCEPTION_H
#define RANDOMACCESSFILENOTFOUNDEXCEPTION_H
#include "RandomAccessFileException.h"
class RandomAccessFileNotFoundException : public RandomAccessFileException
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// This class is defined in the
// RandomAccessFileException.h
// header, so you have to #include
// that header before using this
// class as a base class.
{
public:
RandomAccessFileNotFoundException(const char* p_filename);
const char* getMessage();
};
#endif
Second problem:
Also notice that you have a typo. Your base class is called:
RandomAcessFileException
// ^
Instead of:
RandomAccessFileException
// ^^
Which is the name you are using in RandomAccessFileException.h.
Third problem:
Finally, you are missing a definition of the base class's (RandomAccessFile) constructor, for which you have provided just a declaration:
class RandomAcessFileException
{
public:
RandomAcessFileException();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// This is a DECLARATION of the constructor, but the definition is missing
virtual const char* getMessage() = 0;
protected:
char m_message[100];
};
Without providing a definition, the linker will emit an unresolved reference error.
I asked a while ago how to use virtual classes in c++, and to my dismay i learned that you can't. But one user,(namely "Emilio Garavaglia" thanks a bunch), posted a way to get something similar to virtual classes, just with some extra code. however, i'm having some trouble getting what i'm doing to compile. here's the code:
global_defs.h
#define Interface class
#define abstract_class class
#define implements : public
I_Graphics.h
#ifndef I_GRAPHICS_H
#define I_GRAPHICS_H
#include <string>
#include "global_defs.h"
Interface I_Graphics
{
public:
virtual ~I_Graphics() {};
virtual void Initialize() = 0;
virtual void Frame() = 0;
virtual void Shutdown() = 0;
class I_Model;
virtual I_Model * CreateModel() = 0;
};
Interface I_Graphics::I_Model
{
public:
virtual ~I_Model() {}
virtual void Initialize(std::string const & filename, std::string const & textureFilename) = 0;
virtual void * GetVertexBuffer() = 0;
virtual void * GetIndexBuffer() = 0;
};
#endif
Graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "global_defs.h"
#include <map>
#include <string>
#include <memory>
#include "I_Graphics.h"
class Graphics implements I_Graphics
{
public:
Graphics();
~Graphics();
void Initialize();
void Frame();
void Shutdown();
class Model;
I_Model * CreateModel() {return new Model;} // <--- compile error here
private:
std::map <std::string, I_Model *> m_ModelList;
};
class Graphics::Model implements I_Graphics::I_Model
{
public:
Model();
~Model();
void Initialize(std::string filename, std::string textureFilename);
void * GetVertexBuffer();
void * GetIndexBuffer();
};
#endif
Graphics.cpp
nothing going here, havn't really started working on the hard part yet, just trying to get the model instantiation to work.
#include "Graphics.h"
Graphics::Graphics()
{
}
Graphics::~Graphics()
{
}
void Graphics::Initialize()
{
}
void Graphics::Frame()
{
}
void Graphics::Shutdown()
{
}
Graphics::Model::Model()
{
}
Graphics::Model::~Model()
{
}
void Graphics::Model::Initialize(std::string filename, std::string textureFilename)
{
}
void * Graphics::Model::GetVertexBuffer()
{
return NULL;
}
void * Graphics::Model::GetIndexBuffer()
{
return NULL;
}
so, as the little comment says, i get an error there saying:
error C2512: 'Graphics::Model' : no appropriate default constructor available
when there obviously is a constructor for it in graphics.cpp . Can someone please explain what the compiler is complaining about here?
EDIT:
not sure if it means anything, but when mousing over the little red squiggle in MSVC, it says, "object of abstract class type Graphics::Model is not allowed" . ...but it doesn't have any pure virtual members, so it's not abstract right?
EDIT:
On the suggestion of Castilho, i declare CreateModel in graphics.h like before, but then defined it in graphics.cpp, and it yielded a much more specific error, but i still don't understand why.
error C2259: 'Graphics::Model' : cannot instantiate abstract class
1> due to following members:
1> 'void I_Graphics::I_Model::Initialize(const std::string &,const std::string &)' : is abstract
1> i_graphics.h(28) : see declaration of 'I_Graphics::I_Model::Initialize'
You're using the Model class before it is defined. Define the function CreateModel in a separate CPP and it may work.