Can't see global variable from header File - c++

I have two header files that rely on each other, but one header file can't see the variables from the other.
This Header files declares the map Agents
#pragma once
#include <agents.h>
#include "Manage_A.h"
class M_Agent : public Concurrency::agent
{
public:
explicit M_Agent(Concurrency::ISource<int>& source, Concurrency::ITarget<wstring>& target) :
_source(source), _target(target)
{
}
protected:
void run() {
cout << "What Would You Like to Do?\n"
<< "1. Manage Agents\n"
<< "2. See Info From Agents\n"
<< "3. Alerts\n"
<< "4. Quit\n";
cin >> choice;
switch (choice)
{
//Manage Agents
case 1:
Manage_A();
run();
break;
//See Info from Agents
case 2:
cout << "INfo\n";
run();
break;
//Alerts
case 3:
cout << "Alerts\n";
run();
break;
//Quit
case 4:
exit(0);
break;
//Try again
default:
run();
break;
}
//done();
}
private:
int choice{ 0 };
Concurrency::ISource<int>& _source;
Concurrency::ITarget<wstring>& _target;
};
extern std::map<string, M_Agent*> Agents;
extern Concurrency::overwrite_buffer<int> buffer1;
extern Concurrency::unbounded_buffer<wstring> buffer2;
This header contains functions using the map
#pragma once
#include"M_Agent.h"
#include"F_Agent.h"
#include"Variables.h"
void Create_A()
{
system("cls");
string name{ "" };
int a_type{ 0 };
std::cout << "Please Name Agent\n";
std::cin >> name;
while (true)
{
std::cout << "What Type of Agent Would You like\n"
<< "1. Main Agent\n"
<< "2. File Agent\n"
<< std::endl;
std::cin >> a_type;
if (std::cin.good())
{
break;
}
else
{
system("cls");
std::cout << "Please enter correct choice" << std::endl;
}
std::cin.clear();
std::cin.ignore();
}
switch (a_type)
{
//Create Main Agent
case 1:
Agents.insert(std::make_pair(name, new M_Agent(buffer1, buffer2)));
system("cls");
break;
//Create File Agent
case 2:
F_Agents.insert(std::make_pair(name, new File_Agent(buffer1, buffer2)));
system("cls");
break;
}
return;
}
The problem is that the second header file says Agents is a unidentified identifier.

Both header files presumably include each other. So the first file includes the second, which then tries to include the first again, but fails, since #pragma once is in force. As a result the necessary definitions for the second file are not available when they are needed.
To fix this you need to break this circular dependency. The best way to do this is by putting the bulk of your code into a .cpp file (instead of dumping the whole thing into headers). This will allow you to reduce the number of includes, hopefully to the point where a cross-include is no longer necessary. You may need some forward declarations to make that work though.

Header files are mainly used for function/variable declarations, not definitions. If you were to create a source file (.cpp) for the definitions of the functions/variables and link that to each header file, you could possibly avoid the errors that you are experiencing.

Related

C++ Multiple Classes in ONE cpp file

I'm required to work with multiple classes in one .cpp file. I'm not sure what I'm doing wrong, is there a header file I need to include?
These are the errors I'm getting:
error C3646: 'loginObject': unknown override specifier
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2065: 'loginObject': undeclared identifier
#include <iostream>
#include <string>
using namespace std;
//Declaration of Class that Allows User to Select a Menu Option
class Menu
{
private:
int userChoice = 0; //User's Menu Selection
//Class Objects
Login loginObject;
public:
void options()
{
//Loop of Initial Menu
do
{
//Startup Menu
cout << "\n\tMain Menu:"
"\n\n\t1. Login"
"\n\t2. Create Password"
"\n\t3. Change Password"
"\n\t4. Delete User"
"\n\t5. Exit"
"\n\nSelection: ";
cin >> userChoice;
cout << endl;
//Switch Statement that Determines Course of Action based upon User's Choice
switch (userChoice)
{
case 1:
loginObject.login(); //Option to Login
break;
case 2:
cout << "\nCreating Password..."; //Option to Create a New Password
cout << endl;
break;
case 3:
cout << "Changing Password..."; //Option to Change an Old Password
cout << endl;
break;
case 4:
cout << "Deleting User..."; //Option to Delete a User
cout << endl;
break;
case 5:
cout << "Exiting..."; //Option to Exit the Program
cout << endl << endl;
system("pause");
default:
cout << "INVALID MENU OPTION!\n";
break;
}
} while (userChoice != 5); //Loop to Return to Initial Menu
}
};
//Declaration of Class that Manages all Activities Dealing with Login
class Login
{
private:
public:
void login()
{
cout << "\nLogging In...";
cout << endl;
}
};
//Main File
int main()
{
//Call to Menu Class
Menu menuVariable;
menuVariable.options();
return 0;
}
Generally speaking, your C++ code is read from top to bottom. So you can't use the name Login before it's defined. In your case, you can just move Login to above Menu (since the former does not depend on the latter) and it'll all be fine. In general, you can write a prototype at the top of your file to indicate the shape of a class without showing its implementation. So, for Login, that would be
class Login {
public:
void login(); // Note: No function body
};

C++ beginners question how to access variables

So basicly my questions include when to use parameters and when I dont need them.
I try to learn from examples and this one I can't fully understand:
I will add the questions to the part where I dont understand something after "//" on the right side of the line.
Maybe someone can give me a good explanation, what I need to do in which scenario or good sources where I can look this up on my own.
class Student with public attributes:
#include <iostream>
class Student
{
public:
int stud_ID;
char stud_Name[22];
int stud_Age;
};
function which I want included in int main():
void studentinformation(Student); //#1Why do I must include (Student) in this fuction? ->
// If I dont add this parameter in here, there is no connection ->
//to the function studentinformation(s) in int main.
//Why exactly is that the case ?
main function to get information:
int main(){
Student s;
std::cout<<"Type in ID:";
std::cin >> s.stud_ID;
std::cout<<"Type in youre Name:";
std::cin.ignore(); //
std::cin.getline(s.stud_Name, 22); //#2 Why is std::getline(std::cin, s.stud_Name) not working ?->
std::cout<<"Type in age:"; //#3 Or is there a better alternative ?
std::cin >> s.stud_Age;
studentinformation(s); //#4 Why do I must include the parameter s ?
return 0;
}
function to print information:
void studentinformation(Student s) // #5 Why do I must include the Parameters ?
{ std::cout<<" Student information:"<< std::endl;
std::cout<<" Student ID:" << s.stud_ID << std::endl;
std::cout<<" Name:" << s.stud_Name<< std::endl;
std::cout<<" Age:" << s.stud_Age<< std::endl;
}
studentinformation() is a free function with no connection to any instance of Student which is why you need to supply one as an argument.
std::getline() works on std::strings ...
... and you'd be doing yourself a favour if you changed char stud_Name[22]; to std::string stud_Name;.
For the same reason as in 1.
For the same reason as in 1. 1, 4 and 5 are questioning the same thing.
An alternative would be to make studentinformation() a Student member function instead. You could then call s.studentinformation(); to print info about that particular student.
class Student {
public:
int stud_ID;
std::string stud_Name; // suggested change
int stud_Age;
void studentinformation() const { // const since the object (this) won't be altered
std::cout << " Student information:" << '\n';
std::cout << " Student ID:" << stud_ID << '\n';
std::cout << " Name:" << stud_Name << '\n';
std::cout << " Age:" << stud_Age << '\n';
}
};

Why am I getting an uninitialized local variable error when I have already defined it?

I am a beginner with c++ and I'm having trouble with this error, I am aware that this error means I am trying to use a variable that hasn't been given a value yet.
The context of the program is a that the variable is called option, the value of option is input by the user in a later function. When I started getting this error my only thought was to give the variable a value that was determined in the function so written as "option = enteroption(option);" however it still says the variable is uninitialized. can anybody help explain what I am maybe doing wrong? thanks.
#include "pch.h"
#include <iostream>
#include "Arcade game menu.h"
using namespace std;
int main()
{
char option; //declare variable
float balance; //declare variable
const unsigned char pounds(156); //signatures for functions
void processoption(char, float&, char);
void payinitialfee(float&);
char enteroption(char);
payinitialfee(balance); //call functions
enteroption(option);
while ((option != 'Q') && (balance > 0)); //while option is not Q and balance is greater than 0 call functions
{
processoption(option, balance, pounds);
option = enteroption(option);
}
cout << "Thanks for playing." << endl;
system("pause");
}
void payinitialfee(float& balance)
{
balance = 100;
}
char enteroption(char option)
{
cout << "Enter option..." << endl << "P:Play or B:Balance or Q:Quit" << endl;
cin >> option;
void putinUpperCase(char);
putinUpperCase(option);
return option;
}
void putinUpperCase(char option)
{
option = toupper(option);
}
void processoption(char option, float&balance, char pounds)
{
void playGame(float&); //signatures
void showbalance(float&, char);
switch (option)
{
case 'P': playGame(balance);
break;
case 'B': showbalance(balance, pounds);
break;
default: cout << "ERROR: INVALID COMMAND." << endl;
break;
}
}
void playGame(float& balance)
{
cout << "Playing..." << endl;
balance = balance - 20;
}
void showbalance(float&balance, char pounds)
{
cout << "The current balance is... " << pounds << balance << endl;
}
You are passing the uninitialized variable option to the function enteroption as an argument
option = enteroption(option);
This does not make any sense and the compiler points this to your.
The function can be declared like
char enteroption();
Within the function you can declare a local variable option that will get a value. Then this variable can be returned from the function and is assigned to the variable option declared in main.
Also it seems that the call of the function
putinUpperCase(option);
has no effect because the variable option is not passed be reference. See the function declaration
void putinUpperCase(char);
It seems the function should be declared like
void putinUpperCase( char & );
The compiler is right about this.
In you current code you call option = enteroption(option). At this point option is undefined, which the compiler tells you. You either want to pass option by reference:
void enteroption(char &option)
{
// ...
cin >> option;
// ...
}
Or don't use a parameter here:
char enteroption()
{
char option;
// ...
cin >> option;
// ...
return option;
}
You can pass the reference of local member option from calling function instead of returning a character. The same can be applied to make upper case letter which will ultimately called function can modify the value of the argument by using its reference passed in.
enteroption(option);
void enteroption(char& option)
{
cout << "Enter option..." << endl << "P:Play or B:Balance or Q:Quit" << endl;
cin >> option;
void putinUpperCase(char&);
putinUpperCase(option);
return;
}
void putinUpperCase(char& option)
{
option = toupper(option);
}

How to declare a global object in a switch statement

I am having a problem, where I need to declare an object for a class based on user input. The problem is that the scope of the object is stuck in the switch statement, and I was wondering if there was a way to make it public.
//ask the user to choose the class of the first fighter
cout << "Welcome to the fighting arena! Would you like the first competitor to be a FIGHTER <1>, a WIZARD <2>, a ROGUE <3>, or a RANGER <4>?" << endl;
cin >> competitor1;
cout << "And what is the name of the competitor?" << endl;
cin >> name1;
//creates an object in the appropriate class and initializes it
switch (competitor1)
{
case 1:
{
Fighter Battler1(name1);
break;
}
case 2:
{
Wizard Battler1(name1);
break;
}
case 3:
{
Rogue Battler1(name1);
break;
}
case 4:
{
Ranger Battler1(name1);
break;
}
default:
cout << "Sorry please enter a valid number!" <<endl << endl;
break;
}
cout << Battler1.hp //this is undefined because of the scope
Yes everything is written inside the main fuction, I know the probelm is scope and just need a way to get around it.
I wouldn't use a switch case at all here, instead, an array of functors, that each create a different type of fighter and return a pointer to their base, i.e.
template<typename T>
std::unique_ptr<Champion> Create( ) { return std::make_unique<T>( ); }
std::function<std::unique_ptr<Champion>(void)> createFunctions [] = {
Create<Fighter>
,Create<Rogue>
,Create<Wizard>
,Create<Ranger>
};
Usage:
std::cin >> competitor1;
std::unique_ptr<Champion> Battler1 = createFunctions[competitor1];
std::cout << Battler1->hp;
You cannot do it as you described. You will need some kind of polymorphism: an object that will change it's behavior depending on it's type.
The most straightforward way to do it would be to use a variant:
using Battler = std::variant<Fighter, Wizard, Rogue, Ranger>;
auto battler1 = [&]() -> std::optional<Battler> {
switch (competitor1)
{
case 1:
return Fighter{name1};
case 2:
return Wizard{name1};
case 3:
return Rogue{name1};
case 4:
return Ranger{name1};
default:
cout <<"Sorry please enter a valid number!" << endl;
return std::nullopt;
}
}();
// if a valid number has been chose.
if (battler1) {
cout << std::visit([](auto& battler) { return battler.hp; }, *battler1);
}
Note that you need an up to date compiler, or using boost::variant instead. This solution might also not be the most scalable as you'll need to effectively update the Battler alias when adding a new battler type.
Also, you could use polymorphism through pointers and vtables. It require more changes to your program, but might be more appropriate in some cases:
struct Battler {
virtual int getHp() const = 0;
virtual ~Battler() = default;
};
struct Fighter : Battler {
int getHp() const override {
return hp;
}
};
struct Wizard : Battler {
int getHp() const override {
return hp;
}
};
// ... all other classes of Battler
Then, change you switch case accordingly:
std::unique_ptr<Battler> battler1;
switch (competitor1)
{
case 1:
battler1 = std::make_unique<Fighter>(name1);
break;
case 2:
battler1 = std::make_unique<Wizard>(name1);
break;
case 3:
battler1 = std::make_unique<Rogue>(name1);
break;
case 4:
battler1 = std::make_unique<Ranger>(name1);
break;
default:
cout << "Sorry please enter a valid number!" <<endl << endl;
break;
}
// if a valid number has been chose
if (battler1) {
cout << battler1->getHp();
}
If you could make the object (Battler1) global, what datatype would it be? Instance of class Fighter, Wizard, Rogue or Ranger?
The solution to your problem is this: Create a parent class (let's say, Character) from which all the others (Fighter...) will inherit: class Fighter : Character etc. And then, create the objects dynamically:
Character *battler;
switch (...) {
case 1:
battler = new Fighter(name);
break;
case 2:
battler = new Wizard(name);
break;
}
// don't forget to free the memory when not needed anymore
delete battler;

C++ Identifier "_var" is undefined

I am attempting to learn C++ (currently only know PHP and some C#) and have run into my first issue.
I am trying to call a class inside a switch, then use that defined variable after the switch. However, I get the error described in the title.
#include <iostream>
#include <string>
using namespace std;
class Hero {
protected:
int hHealth,hStamina,hExp;
string hName;
public:
void Create(string);
string GetName() {
return this->hName;
}
};
class Wizard:public Hero {
public:
void SetStats(string hName) {
this->hName = hName;
this->hHealth = 40;
this->hStamina = 80;
}
};
int main() {
string hName;
int hClass;
cout << "Welcome to Ryan's Dungeons & Dragons Adventure!\n\n";
cout << "Enter your Heroes name\n";
cout << "Name: ";
cin >> hName;
cout << hName << ", please select your class\n";
cout << "(1) The Wizard\n";
cout << "(2) The Warrior\n";
cout << "(3) The Rogue\n";
cout << "(4) The Priest\n";
cout << "Class: ";
cin >> hClass;
switch (hClass) {
case 1:
Wizard _hero;
break;
}
cout << _hero->GetName();
system("PAUSE");
return 0;
}
The error in question occurs on the line:
cout << _hero->getName();
where it says _hero is undefind.
_hero is defined only within the scope of that switch statement. You need to create objects in the same or higher up scope that you'll be using them.
One way you can get around this is define a pointer to Hero before the switch (initializing to null) and then set it to a value inside the switch. For instance:
Wizard *_hero = NULL;
switch (hClass) {
case 1:
_hero = new Wizard();
break;
}
}
if (_hero) {
cout << _hero->GetName();
}
You're also using the -> on a class value (as opposed to a pointer to one). Scope issues aside, you probably intended to write _hero.GetName(). Inside your class, -> is right however since this is a pointer to your object.
switch (hClass) {
case 1:
Wizard _hero;
break;
} // <-- _hero is deallocated at this point
cout << _hero->GetName();
The scope of _hero is limited to the switch statement.
I don't think that even works in C#... what you want is a pointer that's going to be initialized in the switch statement:
Hero* _hero = 0;
switch(hClass){
case 1: _hero = new Wizard;
break;
}
// use _hero ...
// at the end, delete it
delete _hero;
Though, you now most likely need a virtual destructor and virtual functions. Read up on them, they're a powerful OO feature. But you probably know about them from C#.
You said you know some C# and php, which I do not. I just want to know how would this have behaved in C#.
Creating an object inside some scope and using it outside the scope. Like: {int a;} a = 0;
In C++ its an issue.
switch (hClass) {
case 1:
Wizard _hero;
break;
}
//At this no _hero is present. _hero is out of its scope
The _hero object is restricted to the scope of that switch block. What you want is probably this:
Hero* _hero;
switch (hClass) {
case 1:
_hero = new Wizard();
break;
}
cout << _hero->GetName();