I have a base class and 3 separate derived classes. All of the .hpp files are structured the same.
The .hpp which doesn't work:
#ifndef CAESARCIPHER_HPP
#define CAESARCIPHER_HPP
#include "Cipher.hpp"
#include<string>
class CaesarCipher : public Cipher {
public:
CaesarCipher(Key key)
: Cipher{ key } {}
std::string getCipherTypeString() const override {}
};
#endif
The .cpp of it (haven't implemented anything yet):
#include "CaesarCipher.hpp"
#include "Cipher.hpp"
#include<iostream>
CaesarCipher::CaesarCipher(Key key)
: Cipher{ key } {}
std::string CaesarCipher::getCipherTypeString() const {
return "";
}
One .hpp that does work:
#ifndef ASCIICIPHER_HPP
#define ASCIICIPHER_HPP
#include "Cipher.hpp"
#include<string>
class AsciiCipher : public Cipher {
public:
AsciiCipher(Key key)
: Cipher{ key } {}
std::string getCipherTypeString() const override {}
};
#endif
The base.hpp class looks like this:
typedef uint64_t Key;
#ifndef BASE_HPP
#define BASE_HPP
#include <string>
class Cipher {
Key key_;
public:
Cipher(Key key){}
virtual std::string getCipherTypeString() const {}
};
#endif
Errors:
CaesarCipher.cpp:6:15: error: redefinition of 'CaesarCipher'
CaesarCipher::CaesarCipher(Key key)
^
./CaesarCipher.hpp:9:9: note: previous definition is here
CaesarCipher(Key key)
^
CaesarCipher.cpp:9:27: error: redefinition of 'getCipherTypeString'
std::string CaesarCipher::getCipherTypeString() const {
^
./CaesarCipher.hpp:12:21: note: previous definition is here
std::string getCipherTypeString() const override {}
^
The problem is that 2 of the derived classes work perfectly but for one I get the above mentioned error for all of the functions. They look all the same just with changed names etc.
You have to:
Define the type Key.
Provide the missing body for the definition of Base::Base(Key).
Add a return statement to all functions that return non-void.
That should fix the errors that you are getting.
Related
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){}
};
I have two c++ class bellow. I want get LHContactInfo property from LHSceneSubclass but I can get nothing.So How can I do with this?
#ifndef __LEVELHELPER_API_CONTACT_INFO_H__
#define __LEVELHELPER_API_CONTACT_INFO_H__
#include "LHConfig.h"
#if LH_USE_BOX2D
#include "cocos2d.h"
class b2Contact;
using namespace cocos2d;
class LHContactInfo
{
public:
LHContactInfo();
virtual ~LHContactInfo();
Node* nodeA;
Node* nodeB;
std::string nodeAShapeName;
std::string nodeBShapeName;
int nodeAShapeID;
int nodeBShapeID;
Point contactPoint;
float impulse;
b2Contact* box2dContact;
};
#endif
#endif //__LEVELHELPER_API_CONTACT_INFO_H__
#include "LHContactInfo.h"
#if LH_USE_BOX2D
#include "Box2d/Box2d.h"
LHContactInfo::LHContactInfo(){
nodeA = NULL;
nodeB = NULL;
box2dContact = NULL;
}
LHContactInfo::~LHContactInfo(){
nodeA = NULL;
nodeB = NULL;
box2dContact = NULL;
}
#endif
#ifndef __LH_SCENE_SUBCLASS_H__
#define __LH_SCENE_SUBCLASS_H__
#include "cocos2d.h"
#include "LevelHelper2API.h"
class LHContactInfo;
class LHSceneSubclass : public LHScene
{
public:
static cocos2d::Scene* createScene();
LHSceneSubclass();
virtual ~LHSceneSubclass();
bool initWithContentOfFile(const std::string& plistLevelFile);
virtual bool shouldDisableContactBetweenNodes(Node* nodeA, Node* nodeB);
virtual void didBeginContact(const LHContactInfo& contact);
virtual void didEndContact(const LHContactInfo& contact);
};
#endif // __LH_SCENE_SUBCLASS_H__
//file.cpp
void LHSceneSubclass::didBeginContact(const LHContactInfo& contact){
if(contact.nodeA->getName() == "box1"){// error invalid use of incomplete type 'const class
LHContactInfo'
}
}
void LHSceneSubclass::didEndContact(const LHContactInfo& contact){
CCLOG("DIDENDCONTACT...\n");
}
I want to do like contact.nodeA from LHContactInfo in didBeginContact function but compile error ->error invalid use of incomplete type 'const class LHContactInfo'
Note::
- Compile with android NDK 10c
The class LHContactInfo is only declared (ie, know by name), due to your forward declaration. However, the compiler needs the class definition. You need to include the file containing the class definition.
I need to create my own class that inherits from std::exception. I need to do this in separate files. I used the example provided during the lecture, the issue is it was shown in one .cpp file, and once it is split, I get an error. How should I fix it?
RzymArabException.h file: (this is where I get an error at line 11)
#ifndef RZYMARABEXCEPTION_H_INCLUDED
#define RZYMARABEXCEPTION_H_INCLUDED
#include <string>
#include <exception>
using namespace std;
class RzymArabException: public exception {
private:
string s;
public:
RzymArabException(string ss) : s(ss);
virtual ~RzymArabException() throw();
virtual const char* what() const throw();
};
#endif // RZYMARABEXCEPTION_H_INCLUDED
RzymArabException.cpp:
#include "RzymArabException.h"
#include <iostream>
#include <exception>
#include <string>
using namespace std;
RzymArabException(string ss) : s(ss) {}
virtual ~RzymArabException() throw() {}
virtual const char* what() const throw() {
return s.c_str();
}
The error is due to the fact that you have a constructor initialization list but do not have a well formed constructor definition here:
RzymArabException(string ss) : s(ss);
If you want to implement the constructor in the .cpp, declare it correctly in the header:
RzymArabException(string ss);
Note that exception specifications are deprecated, so I have removed them from the code that follows.
Your next problem is that the member definitions all need to be in the RzymArabException scope:
//RzymArabException.cpp
RzymArabException::RzymArabException(string ss) : s(ss) {}
RzymArabException::~RzymArabException() {}
const char* RzymArabException::what() const {
return s.c_str();
}
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.