I am very desperate my other classes which have the same inheritance works, this class that I have written was just so simple, it no longer works. I don't know what to do, this is very very frustrating, in fact it is simple class that defines the enemy which do simple predetermined behavior upon their creation.
#include "RD_Infested.hpp"
#include "World.hpp"
#include "SteeringBehavior.hpp"
RD_Infested::RD_Infested(const string& oname, const sf::Vector2f& position, esc::World & w )
: esc::Critter(oname , position, w),
esc::Offensive(*this)
{
esc::Critter::setPathTraversalPolicy(new esc::SteeringBehavior(*this));
}
RD_Infested::~RD_Infested()
{
}
void RD_Infested::update( float e )
{
if (!esc::Object::isActive() )
return;
esc::Offensive::executeAttackOrder( e );
esc::Offensive::executeDefensiveStance( e );
if ( !esc::Offensive::isOnAttackRange() )
esc::Critter::makePursuit( e );
esc::Critter::getPathTraversalPolicy()->updatePolicy( e );
}
RD_Infested* RD_Infested::getInstance()
{
return this;
}
Here its class header:
#ifndef RD_INFESTED_HPP
#define RD_INFESTED_HPP
#include <SFML/Graphics.hpp>
#include "Critter.hpp"
#include "Offensive.hpp"
class RD_Infested : public esc::Critter,
public virtual esc::Offensive
{
public:
RD_Infested( const string&, const sf::Vector2f&, esc::World& );
virtual ~RD_Infested();
virtual void update( float = 0.0f );
RD_Infested* getInstance();
};
#endif // RD_INFESTED_HPP
So what this class does is to inherit from Critter which is a moving object and Offensive being its behavior so in turn conceptually it becomes 'an Offensive Critter'.
This is the error it gives me:
error: no matching function for call to 'esc::Behavior::Behavior()'|
Here is Offensive class: I have removed the unnecessary functions
#ifndef OFFENSIVE_HPP
#define OFFENSIVE_HPP
#include <string>
using std::string;
#include<stack>
using std::stack;
#include "Behavior.hpp"
#include "Weapon.hpp"
namespace esc
{
class World;
class Object;
class Critter;
class Manager;
class AttackCapability;
// Worlds
class Offensive : public virtual Behavior
{
public:
/****/
protected:
explicit Offensive( Critter * );
virtual ~Offensive();
private:
/****/
};
}
#endif // OFFENSIVE_HPP
And here is Behavior class:
#ifndef BEHAVIOR_HPP
#define BEHAVIOR_HPP
#include<stack>
using std::stack;
#include <string>
using std::string;
#include "Critter.hpp"
namespace esc
{
class World;
class Behavior
{
protected:
explicit Behavior( Critter * );
virtual ~Behavior();
/****/
private:
/****/
};
}
#endif // BEHAVIOR_HPP
This one error I do not know how to fix. I did my research about having default ctor being generated but I still don't know or even understand this kind of problem. I don't know how to fix this one.
Thanks. :)
Your Offensive constructor expects a pointer to a Critter object:
explicit Offensive( Critter * );
but you pass an object to it
esc::Offensive( *this )
as this is a pointer and you dereference it. So just use esc::Offensive(this). But the next point is that this might not be a good idea to pass a this pointer to a base class constructor in the constructors initializer list of the derived class.
error: no matching function for call to 'esc::Behavior::Behavior()'|
Some part of your client probably code tries to create a TestConstructDerived instance using its default constructor.
This default constructor is defined (since it's not disabled by the definition of a constructor with arguments or by = delete), but the default constructor for Offensive isn't, since it has a constructor with arguments defined.
See this question for details about the conditions under which default constructors are defined.
Related
This is related to my last post that you can find here: Creating an unordered_map of std::functions with any arguments. I have now gone ahead and extended this out to classes. So let's say I have three different classes. And these classes all have different methods except for getVariable() and setVariable(int). So for this example we will class them ClassA, ClassB, and ClassC.
I also have a base class which I want to use as my driver. Essentially, if I want to set the variable between ClassA and ClassC I would call the base class' setVariable function.
#ifndef BASE_CLASS_HPP
#define BASE_CLASS_HPP
#include <unordered_map>
#include <functional>
#include <utility>
#include <string>
#include <any>
template<class A, class B>
class BaseClass
{
public:
BaseClass() { bindThem(); }
std::pair<int,int> getValue()
{
// return classA and ClassB's values
}
void setValue(int newVal)
{
auto iter = functions.equal_range("setValue");
std::any_cast<void(*)(int)>(mapIter->second)(newVal);
}
private:
std::unordered_multimap<std::string,std::any> functions;
void bindThem()
{
functions.emplace("setValue",&A::setValue);
functions.emplace("setValue",&B::setValue);
functions.emplace("getValue",&A::getValue);
functions.emplace("getValue",&B::getValue);
}
};
I then have in main:
#include <iostream>
#include "baseClass.hpp"
#include "classA.hpp"
#include "classB.hpp"
#include "classC.hpp"
int main()
{
ClassA a;
ClassB b;
ClassC c;
c.setValue(20);
BaseClass<ClassA,ClassB> base1;
BaseClass<ClassA,ClassC> base2;
base1.setValue(15);
auto values = base1.getValues();
}
I can place the functions withing my map, however, when I try to any_cast I don't get anything in return. I also tried:
std::any_cast<void(A::*)(int)>(mapIter->second)(newVal);
But that also gives me a compiler error of must use .* or ->* and I have tried everything to get it to compile and I don't really know what I am doing wrong. I also realized, if I called it that way, then I wouldn't be able to access B's setVariable function since I am using A's namespace.
Is there anyway I can get this to work how I want it to? I am essentially trying to modify those class values without having to make any copies of those classes and instead directly modify them from within this driver.
I still don't quite understand the purpose of such structure, but here an option how to make it at least compile:
#include <unordered_map>
#include <functional>
#include <utility>
#include <string>
#include <any>
template<class A, class B>
class BaseClass
{
public:
BaseClass() { bindThem(); }
std::pair<int,int> getValue()
{
auto range = functions.equal_range("getValue");
return
{
(a.*std::any_cast<int(A::*)()>(*range.first))(),
(b.*std::any_cast<int(B::*)()>(*range.second))()
};
}
void setValue(int newVal)
{
auto range = functions.equal_range("setValue");
(a.*std::any_cast<void(A::*)(int)>(*range.first))(newVal);
(b.*std::any_cast<void(B::*)(int)>(*range.second))(newVal);
}
private:
std::unordered_multimap<std::string,std::any> functions;
void bindThem()
{
functions.emplace("setValue",&A::setValue);
functions.emplace("setValue",&B::setValue);
functions.emplace("getValue",&A::getValue);
functions.emplace("getValue",&B::getValue);
}
A a;
B b;
};
class ClassA
{
public:
void setValue(int){}
int getValue() {return 0;}
};
class ClassB
{
public:
void setValue(int){}
int getValue() {return 1;}
};
int main()
{
BaseClass<ClassA, ClassB> x;
x.setValue(3);
auto i = x.getValue();
}
Please note several things:
I've added members to BaseClass since to call member functions you need an object to be called on.
I'm using first and last iterators of the range from equal_range, but the order of elements in that range is implementation defined. So to make things work you need to take care of distinguishing which container element corresponds to class A and which to class B.
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;
}
#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 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.