I've begun coding in C++ some months ago and now I have been trying to code this one Tic Tac Toe game in an OO manner, however I have had some trouble calling a member function from, let's say just for the sake of the argument, class A through another member function from class B.
Here is a piece of code just to clear it all out:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
private:
char cBlocks[9];
public:
void setA(int nBlock, const char cCharacter)
{
cBlocks[nBlock] = cCharacter;
}
};
class B
{
private:
char cB;
public:
char getB()
{
return cB;
}
void makePlay(int nB)
{
const char cChar = getB();
A::setA(nB, cChar);
}
};
So, when I try to make this call, from within the B::makePlay(int) function:
A::setA(nB, cChar);
The following error is displayed: "Call to non-static member function without an object argument" .
How can I solve this ? What is wrong ?
All help is appreciated! Thank you!
You need to call setA on an instance of class A
A a;
a.setA(nB, cChar);
Related
I'm trying to set a reference of a non-static function in c++. The function I'm referencing is not from the same c++ file, and I get and error saying :
Cannot create a non-constant pointer to member function.
Main.cpp
#include <iostream>
#include "Test.hpp"
class testClass {
public:
void (*update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &t.update; //This is where the error occurs
return 0;
}
Test.hpp
#ifndef Test_hpp
#define Test_hpp
#include <stdio.h>
class test {
public:
void update() {
//Do something
}
};
#endif /* Test_hpp */
My question is how do you do this without setting update in test class to static?
static void update() {
//Do something
}
Using this code it works, but like I've stated I do not want this functiont to be static.
EDIT :
Because I'm stupid I failed to mention that the class test should be able to be different. Also to the answers I got already I learned that tc.update = &t.update; is wrong.
For Example :
#include <iostream>
#include "Test.hpp"
#include "anotherTestClass.hpp"
//I do not want to use templates if possible
class testClass {
public:
void (*update)(void);
};
int main() {
testClass tc;
test t;
tc.update = &test.update; //I know this is wrong now.
testClass tc2;
anotherTestClass atc;
tc2.update = &atc.update;
//p.s. I'm bad with c++
}
And the error i get now is.
Assigned to 'void (*)()' from incompatible type 'void (test::*)()'
One more thing is I'm using XCode to program, which I believe uses LLVM-GCC 4.2 as the compiler.
class test {
public:
void update() {
//Do something
}
};
class testClass {
public:
void (test::* update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &test::update;
return 0;
}
Your approach is essentially wrong.
Member Function Pointers.
The member in the testClass:
void (*update) (void);
is a function pointer, which is different to a method function pointer. That why in order to compile you should switch to a static method (which is essentially a "normal" function).
A method function pointer should containt the static information about the class the method belongs.
Practically the right way is:
void (test::* ptr_method)(void); // a member pointer to test class
In that way the variable named ptr_method is a method of the class test pointer.
Then,
Get the Address of a method.
Your statement:
tc.update = &t.update; //This is where the error occurs
is simply wrong. The address of a class method is something which is not related with the object of that class.
You can obtain the address of a method with the syntax:
&CLASS_NAME::METHOD_NAME;
Indeed, that statement should be something like:
tc.update = &test::update;
Additional suggestions.
Call a method by means of a method pointer.
Once you have a method pointer it is not so immediate to call the method associated with it.
As I said before, the address of the method is not related with the object of that class, so if you want to call the method you need to provide to the compiler the information about the object on which the method has to be called.
The syntax is something like:
(OBJECT.*METHOD_POINTER)(ARGS...);
Here, I propose a simple demo which shows all what I've just said.
Is there a way to get function pointer for a member function that is private inside a class
class A
{
public:
void callMe()
{
cout<<__FUNCTION__<<endl;
}
private:
void fooMem()
{
cout<<__FUNCTION__<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
auto fp = &A::fooMem;
return 0;
}
Compiling this in vs 2012 c++ compiler causes below error
error C2248: 'A::fooMem' : cannot access private member declared in class 'A'
see declaration of 'A::fooMem'
I looked into a amazing solution to a similar problem (though I am not very clear how this actually works, if someone can explain that would be great too), Here I want the address of the member not to invoke it.
The reason I am asking for the address is I'll be patching this function with a different implementation.
The class as such is not modifiable, But I can inherit if that can help achieve this.
Since you cannot modify the original class, it would be much easier to simply inherit the class and create a duplicate of the function in a public memberspace.
I tried this out and it works as expected, at least with g++:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
void aFunction()
{
cout<<"This is aFunction"<<endl;
}
private:
void anotherFunction()
{
cout<<"This is anotherFunction"<<endl;
}
};
class B: public A
{
public:
void anotherFunction()
{
cout<<"This is also anotherFunction, but it's accessible!"<<endl;
}
};
int main(int argc, char* argv[])
{
A firstClass;
B coach;
firstClass.aFunction();
coach.anotherFunction();
return 0;
}
When I run this code I get the following output:
$ ./a.out
This is aFunction
This is also anotherFunction, but it's accessible!
Proving the compiler understood which version of anotherFunction to use.
#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 am attempting to create an poptart vending machine program within c++ and i am trying to use the this keyword, however i am always getting an error stating 'this' may only be used inside a nonstatic member function. Below is a part of the code that i am getting one such issue in
Code:
#include <iostream>
#include "HasCredit.h"
using namespace std;
void insertMoney(int money)
{
cout<<"You inserted: " << money;
money = money+this->currentContext->getStateParam(Credit);
this->currentContext->setStateParam(Credit,money);
cout<< "Total: "<<money<<endl;
this->currentContext->setState(Has_Credit);
}
Any suggestions onto why i am getting this error will be most appreciated. Cheers.
Edit: the insertMoney method is within a class called HasCredit.
Edit2: member declarations are now made outside of the constructor
Edit3: Added state class declaration
The Class Definition Code is Below:
#include <iostream>
#include "State.h"
#include "StateContext.h"
using namespace std;
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) {
}
void insertMoney(int);
void MakeSelectionCoating(int);
void MakeSelectionFilling(int);
void moneyRejected(void);
void addPopTarts(int);
void dispense(void);
};
The state class declaration code is shown Below:
#include <iostream>
#include "Transition.h"
using namespace std;
class State: public Transition
{
protected:
StateContext* currentContext;
public:
State(StateContext* Context);
};
The this pointer is only valid inside a class. Your insertMoney function is not declared to be in a class. See http://www.learncpp.com/cpp-tutorial/87-the-hidden-this-pointer/.
In your definiton of insertMoney (in the code, not the class), you do not declare it to be a member of hasCredit. You need to use void hasCredit::insertMoney instead.
You probably want to attach insertMoney to a class. Try ClassName::insertMoney in your definition.
The error is telling you exactly why you're getting it.
The solution is to fix the definition of what you intend to be a member function, so that the compiler knows it is a member function. Like this:
// vv THIS WAS MISSING
void HasCredit::insertMoney(int money)
{
...
Your member declarations shown in the question are also in the wrong place. They need to be inside the class body, but outside the constructor. When overriding virtual member functions, you may want to show that to readers by using the virtual and override keywords. (Note, override only works if you have a new, C++11 compiler. For older compilers, use a comment /* override */ instead)
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) { }
// vv THIS....................CANNOT BE INSIDE HERE ^^
virtual void insertMoney(int) override;
...
};
You probably want some of your members to be public as well.
There are a few things wrong:
class definition:
#include <iostream>
#include "State.h"
#include "StateContext.h"
using namespace std;
class HasCredit: public State
{
HasCredit (StateContext* Context) : State(Context) {
}
void insertMoney(int);
void MakeSelectionCoating(int);
void MakeSelectionFilling(int);
void moneyRejected(void);
void addPopTarts(int);
void dispense(void);
};
Note that the methods should be declared outside of the constructor definition.
For the implemenation:
#include <iostream>
#include "HasCredit.h"
using namespace std;
void HasCredit::insertMoney(int money)
{
cout<<"You inserted: " << money;
money = money+this->currentContext->getStateParam(Credit);
this->currentContext->setStateParam(Credit,money);
cout<< "Total: "<<money<<endl;
this->currentContext->setState(Has_Credit);
}
The method must be qualified with the name of the class... otherwise it would be considered a definition of a function... and a function does not have a this
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.