This is my base class Shape.h
#ifndef Shape_H
#define Shape_H
#include <iostream>
using namespace std;
class Shape
{
protected:
string name;
bool containsObj;
public:
Shape();
Shape(string, bool);
string getName();
bool getContainsObj();
double computeArea();
};
#endif
Shape.cpp
#include "Shape.h"
Shape::Shape(string name, bool containsObj)
{
this -> name = name;
this -> containsObj = containsObj;
}
string Shape:: getName()
{
return name;
}
bool Shape::getContainsObj()
{
return containsObj;
}
and this is my sub class. Cross.h
#ifndef Cross_H
#define Cross_H
#include <iostream>
#include "Shape.h"
using namespace std;
class Cross: public Shape
{
protected:
int x[12];
int y[12];
public:
Cross();
double computeArea();
};
#endif
Cross.cpp
#include "Cross.h"
Cross::Cross()
{
for (int i = 0; i < 12; i++)
{
this -> x[i] = 0;
this -> x[0] = 0;
}
}
Shape and Cross are in different files, but inside the same folder. The weird thing is when i compile this, errors that i have never seen before came up such as "In function 'ZN5CrossC1Ev', undefined reference to Shape::Shape(),'ZN5CrossC1Ev', undefined reference to Shape::Shape(), undefined reference to WinMain#16".
I tried to do some debugging myself. When i remove the Cross constructor, it works fine. But i definitely need it. Can anyone explain this to me?
You didn't define the default constructor but you declared it Shape();. The only constructor you defined is the one with string and bool parameters Shape(string, bool);.
adding
Shape::Shape()
{
}
or removing
Shape();
will fix it.
For future debugging read the error more carefully, it explains exactly whats wrong:
undefined reference to Shape::Shape()
You've declared a default constructor for Shape, but not defined it anywhere. The default constructor for Cross uses it implicitly to initialise its base class.
You options are:
Define the constructor, if you want Shape to be default-constructible;
Otherwise, remove the declaration and get Cross to initialise Shape with the other constructor.
Related
I am getting a C2504 compilation error in PlayerController.h saying that my base class (Updateable) is undefined. I have searched for several hours for a solution to a circular inclusion with inheritance problem and their solutions are to remove the circular inclusions and jsut use a forward declaration. As far as I understand, this works if no methods from the forward declared class are called. However, in my program my Updateables class calls a method on its member inherited gameObject object and the GameObjects also call methods on their member Updateables. Because of this, Updateables need to include GameObject.h and GameObjects need to include Updateables.h. This leads to a C2504 in PlayerController.h saying that the base class Updateable can not be found.
Here are my relevant classes:
Component.h
#pragma once
#include "Vector3.h"
class GameObject;
class Component {
public:
GameObject* gameObject = nullptr;
Component();
};
Component.cpp
#include "Component.h"
Component::Component() {}
Updateable.h
#pragma once
#include "Component.h"
#include "GameObject.h"
class GameObject;
class Updateable : public Component {
public:
~Updateable();
virtual void update() = 0;
};
Updateable.cpp
#include "Updateable.h"
Updateable::~Updateable() {
if (gameObject) {
gameObject->removeUpdateable(this);
}
}
GameObject.h
#pragma once
#include "Updateable.h"
#include "GameManager.h"
class Updateable;
class GameObject {
public:
GameObject();
~GameObject();
void runUpdateables();
void addUpdateable(Updateable* updateable);
void removeUpdateable(Updateable* updateable);
private:
vector<Updateable*> updateables;
};
GameObject.cpp
#include "GameObject.h"
GameObject::GameObject() {
updateables = vector<Updateable*>();
GameManager::addGameObject(this);
}
GameObject::~GameObject() {
GameManager::removeGameObject(this);
}
void GameObject::runUpdateables() {
for (unsigned int i = 0; i < updateables.size(); i++) {
updateables[i]->update();
}
}
void GameObject::addUpdateable(Updateable* updateable) {
updateables.push_back(updateable);
updateable->gameObject = this;
}
void GameObject::removeUpdateable(Updateable* updateable) {
auto it = find(updateables.begin(), updateables.end(), updateable);
if (it != updateables.end()) {
updateables.erase(it);
}
}
PlayerController.h
#pragma once
#include "Updateable.h"
//#include "GameObject.h"
#include "Input.h"
class Updateable;
class PlayerController : public Updateable {
public:
float speed = 5.0f;
void update();
};
PlayerController.cpp
#include "PlayerController.h"
void PlayerController::update() {
float x = 0;
if (Input::getKeyDown(GLFW_KEY_A)) {
x = -speed;
}
if (Input::getKeyDown(GLFW_KEY_D)) {
x = speed;
}
cout << x << endl;
gameObject->getRigidBody()->velocity.x = x;
//yes this is a method in GameObject that I removed from this post
//because it would take up more space, rigidbody.h does not create
//a circular dependency
}
GameManager.h
#pragma once
#include "GameObject.h"
#include "PlayerController.h"
class GameManager {
public:
static void init();
static void addGameObject(GameObject* go);
static void removeGameObject(GameObject* go);
static void onFrame();
private:
static vector<GameObject*> gameObjects;
static GameObject* box;
GameManager.cpp
#include "GameManager.h"
vector<GameObject*> GameManager::gameObjects;
GameObject* GameManager::box;
void GameManager::init() {
gameObjects = vector<GameObject*>();
box = new GameObject();
box->addUpdateable(new PlayerController());
}
void GameManager::addGameObject(GameObject* go) {
gameObjects.push_back(go);
}
void GameManager::removeGameObject(GameObject* go) {
auto it = find(gameObjects.begin(), gameObjects.end(), go);
if (it != gameObjects.end()) {
gameObjects.erase(it);
}
}
void GameManager::onFrame() {
for (unsigned int i = 0; i < gameObjects.size(); i++) {
gameObjects[i]->runUpdateables();
}
}
Here is the exact error message: Error C2504 'Updateable': base class undefined Basic Platformer c:\users\default.sixcore-pc\documents\visual studio 2015\projects\basic platformer\basic platformer\playercontroller.h 9
A lot of your files have both #include "Class.h" and class Class; declarations. You never need both; use one or the other.
A definition of a class X must be visible when:
accessing the members of X
creating an object of type X
defining a class derived from X
using X as a template argument to a template which requires the corresponding template parameter to be a complete type (such as what standard library containers require of their element type). Note that this applies when using X, not X*.
In other cases (such as creating a pointer to X or declaring a function taking of returning X), a non-defining declaration (class X;) is enough.
Using these rules (plus moving function bodies from headers to source files when necessary), you can solve any circular dependency issues.
To directly address your files as presented:
Updateable.h does not need to #include "GameObject.h". It doesn't even need the forward declaration of GameObject.
GameObject.h doesn't need any of the two #includes in it.
GameManager.h doesn't need any #includes. It needs a declaration of class GameObject; though.
Descendant class must know the full definition of the base class. Forward declaration is not enough and useless.
#pragma once
#include <string>
#include <iostream>
using namespace std;
class Chess_tool
{
public:
Chess_tool(string color, char name);
virtual bool legal_movement(int source[], int dest[]) const = 0;
private:
string _color;
char _name;
};
Im trying to create chess game, so I create abstract class for chess tool (queen, king, rook...)
I also created king tool to check my code:
#pragma once
#include "Chess_tool.h"
class King : Chess_tool
{
public:
King(string color, char name);
virtual bool legal_movement(int source[], int dest[]);
};
and I create game_board class:
#pragma once
#include "Game_board.h"
#include "Chess_tool.h"
#include <iostream>
#define BOARD_SIZE 8
using namespace std;
class Chess_tool;
class Game_board
{
public:
Game_board();
~Game_board();
void move(string panel);
protected:
Chess_tool* _board[BOARD_SIZE][BOARD_SIZE];
};
the problem is here, when i try to add object to the matrix its show me error :
1 IntelliSense: object of abstract class type "King" is not allowed:
pure virtual function "Chess_tool::legal_movement" has no overrider
#pragma once
#include "Chess_tool.h"
#include "Game_board.h"
#include "King.h"
using namespace std;
enum Turn { WIHTE, BLACK };
class Manager : Game_board
{
public:
Manager();
~Manager();
virtual bool legal_movement(int source[], int dest[]) const = 0;
};
....
#include "Manager.h"
Manager::Manager()
{
_board[0][0] = new King();
}
The member function in the base class is const-qualified, not in the derived class.
So these are not the same functions through inheritance. You've declared a new virtual function, not overriden the first one.
Add const to the second one so that it actually override the base class function.
Remember that for virtual function overriding to kick in, there are a few condition to actually satisfy. They must have:
the same name
the same return type
the same parameters count and type
the same const-qualification (our case here)
a few other minor things (for example, compatible exceptions specifications)
If any condition isn't satisfied, you create a very similar, but different, function for the compiler.
With C++11, you should use override for the functions you want to override, so the compiler knows your intention and tells you that you've made a mistake. E.g.:
virtual bool legal_movement(int source[], int dest[]) override;
// ^^^^^^^^
I a beginner in programming.
I coded two classes(having constructors with requirement to pass arguments) and want to declare and use one class's object in another class.
I have tried to find the solution to my error on many website, but none of them worked. I also saw a solution to this problem using the 'new' syntax.
Please suggest some(any) way to sought out this problem.
A short program similar the one in which I am facing problems is as follows:
(I know this program is stupid but, this is not actual program I am facing problem in. Instead this is a narrowed down version of the part of the program in which I am facing error)
The error is in Class2.h and main.cpp
main.cpp
#include <iostream>
#include "Class2.h"
using namespace std;
int main()
{
Class2 Class2_Obj;
Class2_Obj.Class2_Function(); // error: undefined reference to `Class2::Class2_Function
return 0;
}
Class1.h
#ifndef CLASS1_H_INCLUDED
#define CLASS1_H_INCLUDED
class Class1
{
private:
const int c1_Variable;
public:
Class1(int);
// Displays the value of c1_Variable on output screan
void Class1_Function();
};
#endif // CLASS1_H_INCLUDED
Class1.cpp
#include <iostream>
#include "Class1.h"
Class1::Class1(int receivedInt) : c1_Variable(receivedInt) {}
void Class1::Class1_Function()
{
cout << c1_Variable;
}
Class2.h
#ifndef CLASS2_H_INCLUDED
#define CLASS2_H_INCLUDED
#include"Class1.h"
class Class2
{
private:
Class1 Class1_Obj(4); // 4 is just a random number.
//error: expected identifier before numeric constant
//error: expected ',' or '...' before numeric constant
public:
// Calls Class1_Function()
void Class2_Function();
};
#endif // CLASS2_H_INCLUDED
Class2.cpp
#include <iostream>
#include "Class1.h"
#include "Class2.h"
void Class::Class2_Function()
{
Class1_Obj.Class1_Function();
}
Here are the links to snapshots of the errors:
Screenshot of Error in Class2.h - http://i.stack.imgur.com/WpK9k.jpg
Screenshot of Error in main.cpp - http://i.stack.imgur.com/yDBD7.jpg
Please help me out! Thanks in advance for any responses :)
The issue is that this in-place initialization of non-static data members syntax is invalid:
class Class2
{
private:
Class1 Class1_Obj(4);
....
};
You can use {} instead,
class Class2
{
private:
Class1 Class1_Obj{4};
....
};
or this form
class Class2
{
private:
Class1 Class1_Obj = Class1(4);
....
};
C++ is a Object Oriented Language. It has classes to structure its data.
To put one class into another, you make an object of one class a member of another class.
Syntactically, it works like
class A {
int x;
public:
A (int x1) : x(x1) {}
};
class B {
A a; // this is how you do it ..
public:
B() : A(4) {}
};
B b; // b is an object which has a member b.a
As you can see, b is an object of class B. It has a member a of class A.
I have seen other people asking this question before, but the answers they received were unique to their programs and unfortunately do not help me.
Firstly, I have a shape class - split into .h and .cpp files
//Shape.h
#include <string>
using namespace std;
class Shape
{
private:
string mColor;
public:
Shape(const string& color); // constructor that sets the color instance value
string getColor() const; // a const member function that returns the obj's color val
virtual double area() const = 0;
virtual string toString() const = 0;
};
//Shape.cpp
#include "Shape.h"
using namespace std;
Shape::Shape(const string& color) : mColor(NULL) {
mColor = color;
}
string Shape::getColor() const
{
return mColor;
}
I keep getting an error in my Shape.h class that says 'Shape' : 'class' type redefinition.
Any idea why I might be getting this error?
add include guard to your header file
#ifndef SHAPE_H
#define SHAPE_H
// put your class declaration here
#endif
And the way you initialize member mColor is incorrect. You can't assign NULL to string type
Shape::Shape(const string& color) : mColor(color) {
}
Add virtual destructor to Shape class as it serves as a base with virtual functions.
Also, do NOT use using directive in header file.
It seems like you want to write an abstract base class here, but is there any other files you compiled but not showed here?
You must include “shape.h” twice more.
Just use macros to prevent this case.
PS:I guess Rectangle is base class of Square,and also inherited Shape.
I have a class "board" that I am trying to put a deque member in. I wrote the code with an int object for the deque and everything worked fine, so I think it is a problem with setting the Template for the custom class, but I have never done this in C++.
board.h:
#ifndef __board_h__
#define __board_h__
using namespace std;
#include <deque>
#include "noble_card.h"
class board;
class board
{
public: deque<noble_card> line;
public: board();
public: ~board();
};
#endif
board.cpp:
#include <deque>
#include "noble_card.h"
board::board() {
deque<noble_card> line;
}
board::~board() {}
I think I may have a problem with the construction method here, as deque is erroring out on so many things I am having trouble tracking it down.
noble_card.h:
#include <string>
#ifndef __noble_card_h__
#define __noble_card_h__
#include "board.h"
class noble_card
{
public: string name;
public: int id;
public: int vp;
public: noble_card(int _vp);
public: ~noble_card();
};
#endif
noble_card.cpp:
#include "noble_card.h"
noble_card::noble_card(int _vp) {
this->vp = _vp;
}
noble_card::~noble_card() {
}
Now, the problem comes when I try to push elements onto this deque, i have a for loop like such:
board b;
for (unsigned i = 0; i < 12; i++) {
noble_card nc(i);
b->line.push_back( nc );
}
I keep getting assignment operator could not be generated, copy constructor could not be generated, and std::deque : 'noble_card' is not a valid template type argument for parameter '_Ty' (board.h). I am assuming this is because I haven't templated my classes and overridden the copy/constructor methods to tell the deque how to sort/remove/alloc/copy this type of class. I'm basically just trying to get a custom c++ class to be used in a deque and it is a lot more complicated than C# and other standard libraries I've used where you just push it on there and it takes care of it.
EDIT:
#ifndef __noble_card_h__
#define __noble_card_h__
using namespace std;
class noble_card {
public: char* name;
public: int id;
public: int vp;
public: noble_card(char* _name, int _id, int _vp) : name(_name), id(_id), vp(_vp) {}
};
#endif
Setting up noble_card.h this way seems to satisfy the requirements for the copy/alloc/constructor for deque. I still don't fully understand it as it seems to be shorthand, so if anyone could expand on line 10 I'd much appreciate it. For now This change has me moving forward.
Small fix of your immediate problem:
Your variable b is not a pointer and the operator->
b->line.push_back(nc);
will therefore not work. You have to use the operator.
b.line.push_back(nc);
C++ is not C# (mini code review)
You write that you are coming from C#. There are a lot of stylistic differences between the two languages that you should be aware off. I don't know C#, but here is a 2nd take on your code, taking care of the sorest points (I'm commenting out the header inclusions as it doesn't work on the online compiler I use)
// noble_card.h
#include <string>
class noble_card
{
public: // single section of public stuff (are you sure you don't need private data?)
std::string name; // never do: "using namespace std;" in a header!
int id;
int vp;
noble_card(int _vp);
// compiler-generated default constructor is just fine here
};
// noble_card.cpp
noble_card::noble_card(int _vp): vp(_vp) {} // initialize member in initializer-list
// board.h
// #include "noble_card.h"
#include <deque>
class board
{
public: // single section of public stuff (are you sure you don't need private data?)
std::deque<noble_card> line; // never do: "using namespace std;" in a header!
// compiler generated default constructor and destructor are just fine here
};
// board.cpp (not necessary for your current impl)
// #include "board.h" // takes care of "noble_card.h"
// main.cpp
int main()
{
board b;
for (unsigned i = 0; i < 12; ++i) {
b.line.emplace_back(i); // C++11 allows you to construct-in-place
}
}
Live Example.
You should Google this site to get in-depth explanations of the points that I write in the above code behind the // comments.