I am making a simple C++ game based loosely on Starcraft. This is a way to practice pointers.
The program works fine so now im adding the little technical stuff in this case, the Cloaking ability ghost
In the ghost class, I set up a while loop for while bool cloak == true , you set the hits to blank as the ghost cant be hit while cloaked ( no detectors in this game) When i set it up, it gives me the error " expected unqualified id before while" .If i take out the loop, it doesnt give me an error.
any help is much appreciated
here is my ghost.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#include "ghost.h"
ghost::ghost(string iname, string iteam, string itype, int Snipe, bool cloak)
: infantry(iname, iteam, itype)
{
set_SniperR(Snipe);
set_Cloak(cloak);
set_health(80);
}
void ghost::set_SniperR(int Snipe)
{
SniperR = Snipe;
}
int ghost::get_SniperR() const
{
return SniperR;
}
void ghost::shoot_SniperR(infantry* attacked_infantry)
{
if(SniperR!=0 && this->get_health()!=0 && attacked_infantry->get_health()!=0)
{
attacked_infantry->SniperR_hit();
}
}
void ghost::attack(infantry* attacked_infantry)
{
shoot_SniperR(attacked_infantry);
if (attacked_infantry->get_health() == 0)
attacked_infantry->die();
}
void ghost::heal(infantry* attacked_infantry) { }
void ghost::die()
{
set_SniperR(0);
}
void ghost::set_Cloak(bool cloak)
{
Cloak = cloak;
}
bool ghost::get_Cloak() const
{
return Cloak;
}
while ( cloak) // <-- error
{
void ghost::AssaultR_hit()
{
// when cloak is on , AssaultR doesnt affect Ghost
}
void ghost::FlameT_hit() { }
void ghost::SniperR_hit() { }
void ghost::RocketL_hit() { }
void ghost::StickyG_hit() { }
}
void ghost::print() const
{
cout << endl;
infantry::print();
cout << "Sniper Rifle Rounds: " << get_SniperR() << endl;
}
void ghost::speak() const
{
infantry::speak();
cout << "Did somebody call for an exterminator? " << endl;
}
void ghost::display() const
{
infantry::display();
cout << right << setw(5) << " "
<< right << setw(5) << " "
<< right << setw(10) << get_SniperR()
<< endl;
}
The proper way to do this is to remove the while loop and check if cloak is true in your methods. Here is a implementation that will not give you the errors(assuming cloak is a member variable, which it should be in this case):
void ghost::AssaultR_hit()
{
if(!cloak)
{
//assualtR_hit implementation goes here
}
}
void ghost::FlameT_hit()
{
if(!cloak)
{
//FlameT_hit implementation goes here
}
}
void ghost::SniperR_hit()
{
if(!cloak)
{
//SniperR_hit implementation goes here
}
}
void ghost::RocketL_hit()
{
if(!cloak)
{
//RocketL_hit implementation goes here
}
}
void ghost::StickyG_hit()
{
if(!cloak)
{
//StickyG_hit implementation goes here
}
}
Note: Also note the comment that you can not have a while loop outside of a function in C++ like the commentator said.
Related
This question already has answers here:
How to initialize `std::function` with a member-function?
(3 answers)
Using generic std::function objects with member functions in one class
(6 answers)
Closed 25 days ago.
I'm trying to make a program to have a string input for choosing functions.
My code is as follows:
#include <iostream>
#include <map>
#include <functional>
#include <string>
std::map<std::string, std::function<void(bool)>>functions;
void command_greet(bool new_input);
void command_add(bool new_input);
void command_help(bool new_input);
void commands()
{
functions["hi"] = command_greet; //command
functions["add"] = command_add; //command
functions["help"] = command_help; //command
}
void command_greet(bool new_input)
{
if (new_input)
{
std::cout << "Hello!" << std::endl;
}
else
{
std::cout << "This command greets!\n";
}
}
void command_add(bool new_input)
{
if (new_input)
{
int x, y;
std::cout << "X: ";
std::cin >> x;
std::cout << "\nY: ";
std::cin >> y;
std::cout << "\n" << x + y << "\n";
std::cin.ignore();
}
else
{
std::cout << "This command adds two numbers!\n";
}
}
void command_help(bool new_input)
{
if (new_input)
{
size_t cmd_len = 0;
for (const auto& elem : functions) //calculate length of the longest command
{
if (elem.first.size() > cmd_len)
{
cmd_len = elem.first.size();
}
}
cmd_len += 4; //length plus 4 spaces
for (const auto& elem : functions)
{
std::cout << elem.first;
for (size_t i = 0; i < cmd_len - elem.first.size(); i++)
{
std::cout << ' ';
}
elem.second(false); //command description
}
}
else
{
std::cout << "This command shows commands list!\n";
}
}
int main()
{
commands();
std::string input;
while (true) //endless loop for testing
{
std::cout << "Input: ";
std::getline(std::cin, input);
if (functions.count(input) > 0)
{
functions.find(input)->second(true); //run command
std::cout << std::endl;
}
else if (input == "")
{
}
else
{
std::cerr << "'" << input << "' was not recognized.\n"
<< "Type 'help' for available commands.\n";
std::cout << std::endl;
}
}
return 0;
}
The code above works fine with no problems.
Now I want to convert it to class instead of having "bare" functions.
What I've tried:
Partial contents of cmd_console.h
#ifndef __CMD_CONSOLE__
#define __CMD_CONSOLE__
#include <iostream>
#include <string>
#include <map>
#include <functional>
class cmd_console
{
private:
std::map<std::string, std::function<void(bool)>>m_commands;
public:
cmd_console();
void cmd_logic(std::string new_input);
//...other methods here...
~cmd_console();
private:
void commands_inicialise();
//...other methods here...
void command_help(bool new_input);
//...command methods here...
void command_exit(bool new_input);
};
#endif
Partial contents of cmd_console.cpp
#include "cmd_console.h"
cmd_console::cmd_console()
{
commands_inicialise();
}
void cmd_console::commands_inicialise()
{
m_commands["HELP"] = command_help;
//Error C3867: non-standard syntax; use '&' to create a pointer to member
m_commands["EXIT"] = command_exit;
//Error C3867: non-standard syntax; use '&' to create a pointer to member
}
//...other methods here...
void cmd_console::command_help(bool new_input)
{
//code here
}
//...command methods here...
void cmd_console::command_exit(bool new_input)
{
//code here
}
cmd_console::~cmd_console()
{
}
The problem is here:
m_commands["HELP"] = command_help;
//Error C3867: non-standard syntax; use '&' to create a pointer to member
I'm unable to solve this even that it seems to be simple.
Anyone have an idea how to make it work? Thank you.
I'm trying to use my own list with a class called "NameCard" which has two variables, name and phone.
However, complier crushed when I use LFirst(LData pData).
It worked with simple int type list.
any feedback would be greatly appreciated
Here is my code.
Class name: ArrayList.cpp
int ArrayList::LFirst(LData* pData)
{
if (numOfData == 0)
return 0;
curPosition = 0;
*pData = arr[0];
return 1;
}
Class name: NameCard.cpp
NameCard::NameCard()
{
}
NameCard::NameCard(const char* iName, const char* iPhone)
{
strcpy_s(name, iName);
strcpy_s(phone, iPhone);
}
void NameCard::ShowNameCardInfo()
{
std::cout << "Name: " << name << ", phone: " << phone << std::endl;
}
int NameCard::NameCompare(char* iName)
{
return strcmp(name, iName);
}
void NameCard::ChangePhoneNum(char* iPhone)
{
strcpy_s(phone, iPhone);
}
Class name: NameCardImplementation.cpp
#include <iostream>
#include "ArrayList.h"
#include "NameCard.h"
int main()
{
ArrayList list;
NameCard *pData(NULL);
NameCard nc1("Alice", "010-1111-2222");
NameCard nc2("Brandon", "010-2222-3333");
NameCard nc3("Jack", "010-3333-4444");
list.LInsert(nc1);
list.LInsert(nc2);
list.LInsert(nc3);
//nc1.ShowNameCardInfo();
//list.arr[0].ShowNameCardInfo();
//std::cout << list.LCount() << std::endl;
int a = list.LFirst(pData);
std::cout << a << std::endl;
//if (list.LFirst(pData))
//{
// pData->ShowNameCardInfo();
//}
}
Crash is due to null pointer access in ArrayList::LFirst.
From the limited code you have pasted, I see that there is no memory created for pData.
NameCard *pData(NULL);
Are you attaching the memory for pData anywhere else in your code?
im a beginner in c++ and i am so confused why i am getting an error in my code, could you guys please tell me whats going wrong? im using visual studios 2017.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class Cat {
private:
bool happy;
public:
void speak() {
cout << "meow" << endl;
}
Cat() {
bool newHappy = happy;
happy = true;
}
};
int main()
{
cout << "Starting program..." << endl;
Cat bob;
bob.speak();
if (happy) {
cout << "cat is happy" << endl;
}
else {
cout << "unhappy cat" << endl;
}
cout << "Ending program..." << endl;
return 0;
}
You're trying to reference a variable called happy inside your main function, which doesn't exist in that scope. If you want to see if bob is happy, you could simply write if (bob.happy){ ... and change Cat::happy from private to public, or you could create a getter function like:
class Cat {
private:
bool happy;
public:
bool isHappy() const {
return happy;
}
...
};
and call the function as follows: if (bob.isHappy()){ ...
In this example, the compiler says the function "list" doesn't have a definition, despite me writing one below. If I move the function definition to the top so there is no prototype, it compiles fine.
Can someone explain what's happening here?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void stuff();
void list(vector<string> things);
bool alive = true;
int main()
{
vector<string> things;
things.push_back("Lots");
things.push_back("Of");
things.push_back("Things");
do
{
cout << "What do you want to do?\n\n" << endl;
string input;
cin >> input;
if (input == "stuff")
{
stuff();
}
if (input == "list")
{
list();
}
} while (alive);
return 0;
}
void list()
{
cout << "The things are:\n\n";
for (int i = 0; i < things.size(); ++i)
{
cout << things[i] << endl;
}
}
void stuff()
{
cout << "Some stuff" << endl;
}
Your list function definition signature differs from your function declaration. The function signature should be the same. Your function definition signature should also accept one parameter:
void list(std::vector<string> things)
{
std::cout << "The things are:\n\n";
for (int i = 0; i < things.size(); ++i)
{
std::cout << things[i] << '\n';
}
}
And in your program you call the function with:
list();
where it should be:
list(things);
void list(vector<string> things); is not the same as void list(). You need to actually define your function as void list(vector<string> things) not just the prototype.
#include <iostream>
using namespace std;
class Machine
{
class State *current;
public:
Machine();
void setCurrent(State *s)
{
current = s;
}
void on();
void off();
};
class State
{
public:
virtual void on(Machine *m)
{
cout << " already ON\n";
}
virtual void off(Machine *m)
{
cout << " already OFF\n";
}
};
void Machine::on()
{
current->on(this);
}
void Machine::off()
{
current->off(this);
}
class ON: public State
{
public:
ON()
{
cout << " ON-ctor ";
};
~ON()
{
cout << " dtor-ON\n";
};
void off(Machine *m);
};
class OFF: public State
{
public:
OFF()
{
cout << " OFF-ctor ";
};
~OFF()
{
cout << " dtor-OFF\n";
};
void on(Machine *m)
{
cout << " going from OFF to ON";
m->setCurrent(new ON());
delete this;
}
};
void ON::off(Machine *m)
{
cout << " going from ON to OFF";
m->setCurrent(new OFF());
delete this;
}
Machine::Machine()
{
current = new OFF();
cout << '\n';
}
int main()
{
void(Machine:: *ptrs[])() =
{
Machine::off, Machine::on
};
Machine fsm;
int num;
while (1)
{
cout << "Enter 0/1: ";
cin >> num;
(fsm. *ptrs[num])();
}
}
There are a few bits of code I don't completely understand.
First, what does this do exactly?
(fsm. *ptrs[num])();
It looks like it's calling a default constructor of state, but I am not totally sure. Also, I don't understand where the on and off method is called. I think the object machine is the calling object for the on and off method, but I am not even sure.
Lastly, why do we destroy this?
void on(Machine *m)
{
cout << " going from OFF to ON";
m->setCurrent(new ON());
delete this;
}
Is it only for memory management?
I have rewritten the code with two function pointers and some comments:
Instead of array of function pointers, I have used 2 diff pointers and I am using if else for making the decision for switching state.
Main:
int main()
{
void (Machine::*offptr)() = &Machine::off; //offptr is a member funct pointer that now points to Machine::off function
void (Machine::*onptr)() = &Machine::on; //onptr is a member funct pointer that now points to Machine::on function
Machine fsm;
int num;
while (1)
{
cout<<"Enter 0/1: ";
cin>>num;
if( num == 0 )
{
(fsm.*offptr)(); //Here your are calling the function pointed to by the offptr (i.e., Machine::off) using the pointer
}
else if( num == 1 )
{
(fsm.*onptr)(); //Here your are calling the function pointed to by the onptr (i.e., Machine::on) using the pointer
}
}
}
In your example, all the decision is taken with the help of pointer array indices it self. So if user presses 0 the function pointed by ptrs[0] will be called and for 1 the function pointed by ptr[1] will be called. But since there is no check to make sure the user entered 0/1, the program will crash if the user enters something other than 0 or 1.
void on(Machine *m)
{
cout << " going from OFF to ON";
m->setCurrent(new ON()); //Here you are changing the state of the machine from OFF to ON (Note: call comes to this function only if the previous state was OFF).
delete this; //The previous state instance (OFF state pointed by this pointer) of the machine is no more required. So you are deleting it.
}