I have the following code in my program for a blackjack game:
Player *p;
Deck *d = new Deck();
Hand *playerHand = new Hand(), *dealerHand = new Hand();
p = get_Simple(); //This returns a pointer to an instance of a Simple Player for my game
Card dealerCard = d->deal();
p->draw(dealerCard, playerHand);
draw is defined as
virtual bool draw(Card dealer, const Hand &player);
When I try to run this code, I get the following error:
error: no matching function for call to 'Player::draw(Card&, Hand*&);
note: candidates are: virtual bool Player::draw(Card, const Hand&);
The quick-fix would be to match the call with the signature:
p->draw(dealerCard, *playerHand);
The correct way would be to go about your code and get rid of dynamic allocation and raw pointers, replacing them with smart pointers.
The error message is quite clear (after seeing it a couple of times):
error: no matching function for call to 'Player::draw(Card&, Hand*&);
note: candidates are: virtual bool Player::draw(Card, const Hand&);
In the code you are trying to pass a Card and a Hand* to a function, but the compiler did not find an overload that takes those. The closest it got is a function that takes a Card and a const Hand&.
You need to dereference the pointer to get to the object:
p->draw(dealerCard, *playerHand);
Alternatively consider whether you need to hold all objects by pointer or not. Code is much simpler if you avoid pointers.
Related
I am using a library called "Pixel Game Engine", which has a Sprite and a Decal class. The documentation uses std::unique_ptr to create them, so I want to do the same to avoid any complications that may come later on.
Here is my code:
class Asset
{
private:
typedef std::unique_ptr<olc::Sprite> uniqueSprite;
typedef std::unique_ptr<olc::Decal> uniqueDecal;
private:
uniqueSprite LoadAssetImage(std::string fileName)
{
return std::make_unique<olc::Sprite>(fileName);
}
uniqueDecal MakeDecalFromSprite(uniqueSprite sprite)
{
return std::make_unique<olc::Decal>(sprite.get());
}
public:
uniqueSprite rockSprite = LoadAssetImage("rock.png"); //No Error here
uniqueDecal rockDecal = MakeDecalFromSprite(rockSprite); //Error here
};
Error:
function "std::unique_ptr<_Ty, _Dx>::unique_ptr(const std::unique_ptr<_Ty, _Dx> &) [with _Ty=olc::Sprite, _Dx=std::default_delete<olc::Sprite>]" cannot be referenced -- it is a deleted function
At first, I thought this is happening because the unique_ptr is being copied, but loading the sprite using LoadAssetImage() and assigning it to a variable works fine, so I am a little confused as to why this error is happening.
This is how the documentation loads them:
// Load Fragment Sprite
sprFragment = std::make_unique<olc::Sprite>("./gfx/tut_fragment.png");
// Create decal of fragment
decFragment = std::make_unique<olc::Decal>(sprFragment.get());
But I wanted to try something new :)
MakeDecalFromSprite passes a uniqueSprite by value, which involves making a copy. But std::unique_ptr has a deleted copy constructor so when you try to call MakeDecalFromSprite you get a compilation error.
The solution is to pass sprite by const reference instead:
uniqueDecal MakeDecalFromSprite(const uniqueSprite& sprite)
...
Then, you are not asking the compiler to make a copy.
This call:
uniqueSprite rockSprite = LoadAssetImage("rock.png");
works because of NVRO. This avoids the need to copy the function result. If this is not possible for any reason, the compiler can generate a move (std::unique_ptr is moveable).
I am trying to use vector of function pointer in C++ which belongs to one class and being called in another class. For example: In class BoundaryCondition (file BoundaryCondition.h), I initialize the function pointer as:
class BoundaryConditions{
public:
// Constructor function
BoundaryConditions(int id = 0);
vector <void (BoundaryConditions::*) (Face &, int, int)> func2bcond;
void fixedValue(Face &face, int id, int rkStep);
// and other functions with similar definition as fixedValue
}
In another class (DG.h), I initialize an array of BoundaryCondition instance, something like
BoundaryCondition *bcond;
and assign memory to bcond variable using new (in file DG.cpp). For each bcond[i] instance, I need to assign memory to function pointer as:
this->bcond[i].func2bcond.resize(totNoOfVariable);
I am using resize instead of pushback as file reading may not be in the required order. Next, I am assigning function to this function pointer (again in DG.cpp) as per my boundary condition file:
bcond[i].func2bcond[j] = (&BoundaryConditions::fixedValue);
The code compiles alright till this point. I am getting error when I try to call these functions. I call this in DG.cpp. The code is as follows:
(bcond[i].*func2bond[j])(f,1,2);
I keep getting the following error:
error: 'func2bcond' was not declared in this scope
I am quite sure it is only matter of position of * or the brackets, but I am stuck here and I did not get any specific solved post on stackoverflow.
Thanks in advance
Pointer on method requires instance when called, so your code might look like:
(bcond[i].*(bcond[i].func2bond[j]))(f, 1, 2);
or, splitting expression:
auto methodPtr = bcond[i].func2bond[j]; // auto is `void (BoundaryConditions::*) (Face &, int, int)`
(bcond[i].*methodPtr)(f, 1, 2);
FILE *LCD_stdout = new FILE();
int (*ptr)(char, FILE *) = ROBOT::__LCD_putchar;
fdev_setup_stream(LCD_stdout, ptr, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
gives me error:
In member function 'SUBSYS_OPENSTAT ROBOT::LCD_open()':
LCD.cpp:108: error: argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)'
I've looked at a number of solutions through Stack Overflow and whatnot. .* doesn't resolve it, tried assigning a pointer of a pointer, and I feel I'm likely not going to be resolve it without resolving misconceptions.
The compiler error tells you exactly what's wrong:
argument of type 'int (ROBOT::)(char, __file*)' does not match 'int (*)(char, __file*)
...because pointers to member functions aren't compatible with pointers to non-member functions, for a couple of reasons.
One option is to create a separate free function but this depends on where the ROBOT object resides. For example if you have a global ROBOT object you could do the following
ROBOT globalRobot;
int callback(char c, FILE* f)
{
return globalRobot.__LCD_putchar(c, f);
}
FILE *LCD_stdout = new FILE();
fdev_setup_stream(LCD_stdout, callback, NULL, _FDEV_SETUP_WRITE );
stdout = LCD_stdout;
If there is only going to be one robot object and it is a member variable of another class change globalRobot to be a pointer and set it after the ROBOT object has been created (ROBOT's constructor maybe)
This is untested as I don't know the innards of ROBOT but everything looks ok.
I got some problems in creating my program for mobile using QT C++
When i run it i get this: cannot convert 'std::string' to 'std::string*' in initialization
And theres code for that error:
void rozvrh_b17::pars(string par)
{
data = new std::string*(par);
printf(data->data());
}
//data and par are std::string
//without that new std::string*() it does similiar error
And i ask how to convert std::string to std::string* ??
EDIT:
i made this function to transfer data from one form to another and i need to remember that parameter...
I downvoted you because this question shows no research effort.
string * data = ∥
std::string* is a pointer type. You have a std::string, and it's address is the pointer type you want. This is one of the first principles of using pointers.
What do you really try to do?
If you just want to print the string then this should work:
void rozvrh_b17::pars(string par)
{
printf(par.c_str());
}
If you want to create a copy of string on the heap then you need this:
std::string* data = new std::string(par);
but that doesn't make much sense.
You are trying to assign a string from a pointer to string. In this particular case I see several things.
You don't need a copy at all - simply use par right away
You better make par a const ref: void rozvrh_b17::pars(const string& par)
You should use only string whaen calling new otherwise you create a pointer to string. So do: data = new std::string(par);
I am learning C++ and very new at using classes, and I am getting very confused in trying to use them. I am trying to convert my existing code (which used structs) so that it uses classes - so while I know what I am trying to do I don't know if I'm doing it correctly.
I was told that when using functions from the class, I first need to instantiate an object of the class. So what I have tried (a snippet) in my main function is:
int main()// line 1
{
string message_fr_client = "test"; //line2
msgInfo message_processed; //line 3
message_processed.incMsgClass(message_fr_client); //line 4
if (!message_processed.priority_check(qos_levels, message_processed)) //line 5
cout << "failure: priority level out of bounds\n"; //line 6
return 0; //line 7
}
Could you help me clarify if my following assumptions are correct? The compiler is not showing any error and so I don't know if it is error-free, or if there are ones lurking beneath.
At line 4, is the function incMsgClass being performed on the string message_fr_client and returning the resultant (and modified) message_processed?
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/*arguments*/)?
I haven't included the body of the functions because I know they work - I would just like to find out how the class functions interact. Please let me know if I can be clearer - just trying to clear up some confusion here.
Here is my class:
#ifndef clientMsgHandling_H
#define clientMsgHandling_H
#include <list>
#include <map>
#include <queue>
class msgInfo
{
public:
msgInfo();
msgInfo(int, int, int, std::string, std::list<int>);
/*classifying message*/
msgInfo incMsgClass(std::string original_msg);
/*message error checks*/
bool priority_check(int syst_priority, msgInfo msg); //check that message is within qos levels
bool route_check(std::map<std::pair<int, int>, int> route_table, msgInfo msg); //check that route exists
void getPath(msgInfo msg, std::map<std::pair<int, int>, int> route_info, int max_hop);
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
#endif
While it may compile (and even run), there are a few oddities with the code as shown:-
First off, class methods know which object they are operating on - so your priority_check and route_check methods probably don't need msgInfo as a parameter.,
for example, your old non-class function might be like this
bool priority_check(int p, msgInfo msg)
{
return msg.priority < p;
}
But the new one should look like this:
bool msgInfo::priority_check(int p)
{
return priority < p;
}
Also, incMsgClass is a bit odd, as it's a non-static class method that returns a msgInfo object. It's difficult to tell without understanding what it's supposed to do, but it seems possible that this function should actually be a constructor, rather than a regular method.
One other thing is that you're currently passing a msgInfo by value to those methods. So if the method needed to modify the passed msgInfo, it would not have any effect. It's generally better to pass objects by reference or const reference to other methods. So, back to the previous non-method example, it should really be this.
bool priority_check(int p, const msgInfo &msg)
...
But, as I said, you probably don't need the msgInfo parameters anyway.
At line 4, is the function incMsgClass being performed on the string message_fr_client
Yes
and returning the resultant (and modified) message_processed?
Whatever it's returning, you're ignoring the return value. It can modify the object itself, yes, because the function is not const.
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
Yes
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/arguments/)?
If a member function is intended to modify one of the class members, it's just a matter of not marking that function const
Hard to tell without implementation-details, but here we go:
I. You are passing a std::string as value (C++ is call-by-value by default), so you get a copy of the std::string in your method. If you want to work on the object you passed and manipulate it, use a reference on the object, like
msgInfo incMsgClass(std::string& original_msg); // notice the ampersand
then you can change your signature to
void incMsgClass(std::string& original_msg);
as you don't need to return the std::string you passed.
II. Yes, at least according to your signature
III. Can see a node_path only as a member.
For all your questions, see C++-FAQ.
Your basic assumptions are correct.
message_processed.incMsgClass(message_fr_client); //line 4
This line is not correct. The function you call returns msgInfo which is simply dropped. You should assign it to something. But it is not as it is usually done. You should make it a constructor of msgInfo, like
class msgInfo
{
public:
msgInfo(std::string original_msg);
...
}
Then you could call it like this
msgInfo message_processed(message_fr_client);
That line would create a msgInfo that is already properly initialized.
There is another pattern for creating class instances - static creating function. In your case you could mark incMsgClass static and then call it like
msgInfo message_processed = msgInfo.incMsgClass(message_fr_client);
I seriously doubt you need this pattern here, so I'd advise to move to constructor.
As of other functions, I see no problems there. Just note that all member functions not marked as const can modify the object they are called on. So, you don't need to pass this object explicitly. For functions a pointer to the object they are called on is available by name this. Also the functions can access all class variables as if these variables are global for normal (non-member) functions.