How to bring member function in scope? - c++

So I am calling a function which takes input as limit i, and array of objects h.
#include<iostream>
#include<vector>
using namespace std;
class hotel
{
private:
string name,add;
char grade;
int charge,no;
public:
void getdata();
void putdata();
void grade_print(int,hotel[]);
void room_charge();
void top2();
};
void hotel::getdata()
{
cout<<"Add Name: ";
getline(cin>>ws,name);
cout<<"Add Addres: ";
getline(cin>>ws,add);
cout<<"Enter grade,room charge and no. of rooms: ";
cin>>grade>>charge>>no;
}
void hotel::putdata()
{
cout<<name<<endl<<add<<endl<<grade<<endl<<charge<<endl<<no;
}
void hotel::grade_print(int num,hotel h[])
{
int i,j,k; char val;
for(i=0;i<num;i++)
{
val=h[i].grade;
for(j=0;j<num;j++)
{
if(h[j].grade==val)
{
cout<<h[j].grade<<endl;
h[j].grade=' ';
}
}
}
}
int main()
{
std::vector <hotel> h(1);
int i=0,j;
cout<<"Want to add hotel? Press 1: ";
cin>>j;
while(j==1)
{
h[i].getdata();
h.resize(2);
i++;
cout<<"Want to add more? Press 1 for yes, 0 for no: ";
cin>>j;
}
grade_print(i,h);
}
error here is showing that the grade_print is out of scope. Also the grade is a private member but is called by member function. So why is it showing that grade can't be called. Please tell me why so and what can I do to fix it?
Edit1: Declaring function as static void is not helping as the compiler is showing function can't be declared as static void.
D:\C++ Programs\testfile.cpp|30|error: cannot declare member function 'static void hotel::grade_print(int, hotel*)' to have static linkage [-fpermissive]|

From what I can understand, grade_print prints out information about a group of hotels passed as a parameter. If you have a function that acts on a group of a certain class, that function should not be a member of that class. Instead, it should just be a function not associated with any class. This also fixes your scope problem, as it would then have global scope.
If my argument seems weird, think about it like this. Let's say I have a class called number, as well as a function called print_nums which prints an array of numbers passed to it. Would I make print_nums a global function, or a member of the class number? The first one, right? The second one, although it would work, just doesn't really make sense.

grade_print(i, h);
A non-static member function should be called on a specific object like :
h[i].grade_print(i, h);
But, In your case grade_print have to be static, so it should be declared like this:
static void grade_print(int,hotel []);
And the definition goes like normal.
Also, after making grade_print static, you have to call it like this:
hotel::grade_print(i, h);

Related

Using a class and functions to keep track of user stats

I am new to C++, and was wondering what I am doing wrong.
I am trying to create a text-based adventure game that keeps track of player stats using an add or remove function. Currently, my function does not add five points to trust and I am trying to get it to.
#include "function.h"
using namespace std;
int main() {
double trust=100;
editPlayer user(100);
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust);
cout << trust;
Here is my function.cpp only using trust as an example:
#include "function.h"
editPlayer::editPlayer(double trust) {
}
void editPlayer::addTrust(double trust){
trust +=5;
}
void editPlayer::removeTrust(double trust){
trust -=5;
}
And here is my function.h:
#include<iostream>
#include<string>
using namespace std;
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
Lets take your addTrust function:
void editPlayer::addTrust(double trust) {
trust += 5;
}
This will modify the local variable trust, and then the function will end. When the function ends, the life-time of the local variable trust also ends, and the modifications you made to it will be lost.
If you truly want to modify the argument, you need to either pass it by reference:
void editPlayer::addTrust(double& trust) {
trust += 5;
}
Or return the new value:
double editPlayer::addTrust(double trust) {
return trust + 5;
}
If you return the new value, you need to assign to it when calling the function:
trust = user.addTrust(trust);
With the above said, the code and the editPlayer class doesn't make much sense. There's just no need for a class editUser really. Possibly addTrust could be a non-member function, or maybe not a function at all.
The class name doesn't make sense, since it doesn't "edit" anything. And passing an argument to the constructor also doesn't make sense since the objects doesn't have any internal state (the value passed to the constructor is just discarded).
Currently you're not storing anything specific on behalf of user object (an object of the editPlayer class.
The cout << trust; statement just prints a value of the trust local variable which you declared at the beginning: double trust=100;. Because this variable hasn't been changed anyhow since that initialization it is still equal to 100 and this is what you see.
In order to track any editPlayer-specific information the best idea is to store that information as a data member of the class editPlayer. You can declare a data member representing the trust of an object like this:
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const; // add also this one, will be useful
private:
double m_trust {0}; // <---- here - a data member, aka. a class field
};
Now you must refine you constructor to let it utilize the parameter which it takes and assign its value to this new data member (because currently the constructor does nothing):
editPlayer::editPlayer(double trust) {
m_trust = trust;
}
Now in the member functions that you already have just rename the variable so that it reflects the trust data member (and not the parameter) which effectively will allow to update its value:
void editPlayer::addTrust(double trust) {
m_trust += 5;
}
void editPlayer::removeTrust(double trust) {
m_trust -= 5;
}
double editPlayer::getTrust() const { // add definition of our "getter"
return m_trust;
}
Finally you can replace that cout << trust; which we already discussed (still prints the local variable's value) with an invokation of the getter which yields m_trust's value:
cout << user.getTrust();
and see the actual effect of performing the addTrust() operation as well as get delighted with your legitimate object-oriented program.
In general the code you are asking can be covered by classes, member declarations and also a pinch of object oriented programming.
The internet has lots of good (and less than good) tutorials if you search for it.
I would try my luck with some of the following searches
CPP + classes
CPP + member declarations
CPP + dynamic vs. static memory allocation (pointers and stuff)
object oriented programming (OOP)
The examples on this site provide good (and short :D) examples of alot of basic concepts imho.
https://www.tutorialspoint.com/cplusplus/cpp_classes_objects.htm
Some of the topics also apply to other languages.
The first block with my comments:
#include "function.h"
using namespace std; // dont get into the habbit of using namespace std;
// the above can potentially open up for bugs
int main()
{
double trust=100; // This variable is declared in this scope({ ... })
// and will get deallocated once the scope ends with the character '}'
editPlayer user(100); // instance of editPlayer named 'user' is constructed
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust); // calling function on user object
cout << trust;
}
Now looking at the .h file i would advocate against including headers that you dont use in the header.
For small projects it does not matter at all - but for big projects of thousands lines of code removing unused includes can speed up things.
Some would prefer forward declarations - which you can look into once you are more comfortable with the basics of cpp.
#include<iostream> // not used here
#include<string> // not used
using namespace std; // disaster waiting to happen
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
The .cpp file
#include "function.h"
editPlayer::editPlayer(double trust) {}
// function implementation with argument - but argument is not used - change to void fun(double) -> fun(void) OR fun()
void editPlayer::addTrust(double trust) { trust +=5; }
void editPlayer::removeTrust(double trust) { trust -=5; }
I did an example with class declaration and member variables.
#include <iostream>
#include <string>
// this is a class declaration
class Player
{
protected: // protected member variables
double _trust;
public: // public interface
Player(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const;
};
// Implementation of public interface
// notice _trust is the member defined in the class
Player::Player(double trust) : _trust(trust) {} // constructor
// example of default parameters (do note that only definition or declaration can have them)
// This means that calling the function without arguments will become 5
void Player::addTrust(double trust = 5) { _trust += trust; }
void Player::removeTrust(double trust = 5) { _trust -= trust; }
double Player::getTrust() const {return _trust; }
int main()
{
Player player(100); // this will invoke the constructor - and the player object will get initialised with the given state
std::cout << player.getTrust() << std::endl;
// variable to buffer input data into - assuming type int wrt. following if
int firstChoice;
//asks user choice
std::cin >> firstChoice;
if (firstChoice == 1)
{
player.addTrust(25);
player.addTrust();
}
std::cout << player.getTrust();
}
Happy coding !

array compile time initialisation

I wrote this program but it is showing error
details was not declared in this scope.
How can I correct this code?
#include<iostream>
using namespace std;
class dealer
{
private:
char first_name[30],last_name[30],city[20],phone_number[20];
public:
void accept()
{
details[0].first_name:"Simran";
details[1].first_name:"Palak";
details[0].last_name:"Arora";
details[1].last_name:"Kaur";
details[0].city:"Amritsar";
details[1].city:"Jalandhar";
details[0].phone_number:1234567890;
details[1].phone_number:8987654321;
}
void display()
{
cout<<"Record of first person"<<endl;
cout<<"First name is "<<details[0].first_name<<endl;
cout<<"Last name is "<<details[0].last_name<<endl;
cout<<"City is "<<details[0].city<<endl;
cout<<"Phone number is "<<details[0].phone_number<<endl;
cout<<"Record of second person"<<endl;
cout<<"First name is "<<details[1].first_name<<endl;
cout<<"Last name is "<<details[1].last_name<<endl;
cout<<"City is "<<details[1].city<<endl;
cout<<"Phone number is "<<details[1].phone_number<<endl;
}
};
int main()
{
dealer details[2];
details[0].accept();
details[1].accept();
details[0].display();
details[1].display();
return 0;
}
You are attempting to access details within Dealer::accept(). However, details is a variable local to your main() function. Dealer::accept() is a member of the Dealer class and can only see member variables declared within that class.
Dealer cannot see the variable details that you've declared in main(). If you want the Dealer class to initialize certain members, consider writing functions to set those specific variables. For instance, to set first_name, write a function like:
void Dealer::setFirstName(std::string name)
{
strcpy(first_name, name.c_str()); // Consider changing the type of first_name to
// std::string. No need to use char arrays in this
// day and age
}
int main()
{
dealer details[2];
details[0].setFirstName("Simran");
details[1].setFirstName("Palak");
// etc...
}

Can not store any value

I have started learning C++ recently, doing some simple class/friend function practice, What i was trying to do is, get 2 numbers from user for 2 object of a class by using friend functions only then again using friend function only, multiply those 2 numbers and show on screen. Let's say i typed 2, 3, 4, 5 in order. Expected outputs are 6 and 20, but i can only see 0 and 0 on screen.
#include<iostream>
using namespace std;
class iluvcpp {
int no_1, no_2;
public:
iluvcpp(){}
~iluvcpp(){}
friend void inputno(iluvcpp obj);
friend int multiply(iluvcpp obj);
}multi_1, multi_2;
void inputno(iluvcpp obj) {
cout <<"Enter no 1: ";
cin >> obj.no_1;
cout <<"Enter no 2: ";
cin >> obj.no_2;
}
int multiply(iluvcpp obj) {
return ((obj.no_2)*(obj.no_1));
}
int main() {
inputno(multi_1);
inputno(multi_2);
cout << multiply(multi_1) <<" "<< multiply(multi_2);
cout << endl;
system("pause");
return 0;
}
You pass your objects by value, meaning when you call inputno you're working on a copy. Try changing the function signature to:
void inputno(iluvcpp& obj) {
...
}
Here's an explanation with examples about passing parameters by value vs by reference.
2 suggestions:
A variable/method of a class is private by default. Either make your variables no_1 and no_2 public as well, or write a setter, if you're familiar with it. To have them public by default, use struct, as opposed to class.
As others already have pointed out, you're not modifying multi_1 and multi_2 directly. Either have them passed in by reference (The answer of orip mentions exactly that), or make them return this iluvcpp obj Object and call them like:
multi_1 = inputno(multi_1);
void inputno(iluvcpp obj) has one parameter named obj and no return value. That's the wrong way around here, inputno doesn't need anything from main but it should return something:
iluvcpp inputno(void) { ... or (equivalent) iluvcpp inputno() { ....
You'll need a return something; statement at the end, so C++ knows what value to return from inputno.

Functions and variable declaration in C++

In the following code, why must int nInteger be declared inside int readNumber()'s body, but int nAnswer must be declared inside the () portion of void writeAnswer()? Declaring int nInteger inside the () or declaring int nAnswer inside the function body causes the IDE to complain about too few arguments for said function. Why does this happen?
I'm using Code::Blocks and the included MinGW on a Windows 7.
#include <iostream>
int readNumber()
{
using namespace std;
cout << "Please enter an integer: ";
int nInteger;
cin >> nInteger;
return nInteger;
}
void writeAnswer(int nAnswer)
{
using namespace std;
cout << "The sum is: " << nAnswer << endl;
}
int main()
{
int x;
int y;
x = readNumber();
y = readNumber();
writeAnswer(x+y);
return 0;
}
So basicly the int readNumber() function does not require any argument to be passed. You declare a local variable so the function knows where to assign the value you type in. You declare variable int nInteger and then in the very next line you assign a value to it by calling cin >> nInteger. If there was no variable declared then your program wouldn't know where to store the value that you type in.
You can think of it as of a basket for apples. You have one basket but no apples in it, then someone gives you 2 apples that you put into the basket. In the end the return statement work like you give the basket to someone else.
Function void writeAnswer on the other hand requires an argument to be passed. As you can see there in local variable declared. What it does is to simply display "The sum is: PASSED_ARGUMENT". So basicly if you call your writeAnswer function with number 6 like writeAnswer(6) it will write "The sum is: 6".

Not able to use function variables ? Error expression must have class type

Hey i want to use the function wolves variable in the storyline and im trying to do this :
"\nYou awake on a beach to the sound of"<< Wolves().name; " starving and blood hungry,"
"\nThere is a Rock on the ground. You pick it up";
inventory.push_back("Rock");
But Wolves().name; there is an error as mentioned in the title. Why cant i do this?
Here is the code for the function Wolves:
void Wolves()
{
string name = "Wolves";
int health = 20;
hitPoints() +1;
}
You can't access variables defined in a function from outside the function in C++, but you can change it to a class:
class Wolves {
public:
string name;
// ...
Wolves(); // Constructor
//...
}
To access it you can use
Wolves wolve;
wolve.name = "whateverName"; // or set it in the constructor
cout << wolve.name << endl;
What you did in there is create local variables within the function. Once the function exits, they no longer exist. What you want to do is make a Wolves class and create public member variables to do what you want. For an example,
class Wolves {
public:
string name;
int health;
Wolves(string name, int a);
}
Then on the main function,
Wolves w("Bob", 20);
cout << "The name is: " << w.name << endl;
Will output "The name is: Bob"
void functions don't really do anything unless you pass the value in by reference. If you want to alter the object via void function, you should do something like
void Wolves(Wolves & wolfToChange)
{
wolfToChange.name = "Bob";
}
and that will directly alter the object.
You declared "name" as a local variable in a function called Wolves(), but the code that you were referring to expects the function Wolves() to return an object that has an accessible member name. That is why the compiler is complaining.
The way you wrote the code suggests that Wolves should be a class or struct, not a function.