Direct initialization of object's variable using input from user - c++

For th following code:
#include <iostream>
class Test
{
public:
int i;
void get();
};
void Test::get()
{
std::cout << "Enter the value of i: ";
std::cin >> i; // Line 1
}
Test t;
int main()
{
Test t;
t.get();
std::cout << "value of i in local t: "<<t.i<<'\n';
::t.get();
std::cout << "value of i in global t: "<<::t.i<<'\n';
return 0;
}
Though I know what is happening in the above code i.e. the values are assigned to the local and global t , I am confused by the line 1 as I am unable to understand how the value received from the user by the line 1 is getting assigned to the t.i or ::t.i .
It would be much appreciated If someone can help me explain **behind the scene of above problem **.

Test::get() is a member function.
Inside a member function, you can name any member variable of that class, and it'll affect the object you called the function on.
Read the chapter in your C++ book about classes.

Related

How to get a user's input into a class's member variable and dereference it

class cookie{
public:
cookie() = default;
int*p_member{};
int case{};
private:
};
#include <iostream>
using namespace std;
int main(){
cookie cold;
cout << "Type what you want into the cookie p_member variable " << endl;
std::cin >> cold.*p_member; // this doesn't work
}
I wanna know how to get access to the classes pointer variable put data inside it and then derefrence it.
First things first, make sure that you're not dereferencing a null or uninitialized pointer. Otherwise you'll have undefined behavior.
it's about a member that is a pointer.I would like to assign a value to the member, and then dereference the member so i could print it out.
You can use a pointer to member syntax for this task as shown below:
class cookie{
public:
int var;
int cookie::*p_member=&cookie::var; //p_member can point to an int data member of an cookie object
};
int main(){
cookie cold{};
cout << "Type what you want into the cookie p_member variable " << endl;
std::cin >> cold.*cold.p_member; //take input from user directly into var using member pointer syntax
std::cout << "var: " << cold.var << std::endl; //print var to confirm that it is correctly set
}
Working demo

Memeber variable as class variable in C++ how does it happen?

I have a problem. I am currently working on a small example in c++ and can't figure out the explanation. Here is my problem:
#include <iostream>
using namespace std;
class X{
int& i ; /* int i; */
public :
X(int k=100):i(k){ }
X(`const` X& x):i(x.i){}
void setI(int k){i=k;}
int getI(){cout <<"adresse: "<< &i << " Contenue: "<<i<<endl ; return i;}
};
int main(){
int i =7;
X a(i);
a.getI();
a.setI(5);
a.getI();
cout << "the value of i is: " << i << endl;
X b(a);
b.getI();
cout << "the value of i is: " << i << endl;
X c;
c.getI();
a.getI();
return 0;
}
So what I dont understand is why does the variable member i in the
class X work like a class variable? I have searched online and found
that it is called agregation and that it is used for some reasons but
I can not understand why does it happen? How does the compiler do
that?
Could you please explain this to me. Thanks in Previous.
Your code has undefined behaviour, it doesn't have to work in any way at all.
Here's the problem
class X {
int& i;
public:
X(int k = 100) : i(k) {}
...
};
k is a local variable, a parameter to the constructor. It no longer exists once the constructor has exitted.
But your code takes a reference to that local variable. So your class ends up with a reference to an object wheich no longer exists. This is undefined behaviour.
PS I'm not sure what you mean by class variable vs. member variable. To me those terms mean the same thing. But whatever strange behaviour you are seeing, it's explained by the undefined behaviour that your program has, as described above.
PPS I see class variable means static member variable, makes sense, so ignore the previous paragraph.

Pointer address and reference confusion

I have two nearly identical pieces of code which should produce the same output, except not only are they different, the one line I changed is somehow affecting unrelated output!
#include "stdafx.h"
#include <iostream>
using namespace std;
class Tag {
public:
int num = 0;
Tag* contains = nullptr;
Tag::Tag(int n) { num = n; }
void setContains(Tag t) { contains = &t; }
int getNum() { return num; }
Tag getContains() { return *contains; }
};
int main() {
Tag tag1 = Tag(1); Tag tag2 = Tag(2);
tag1.setContains(tag2);
cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;
return 0;
}
This outputs
8460735
8460735
or some other random number. Which tells me I'm somehow outputting the pointer address and not the object it's referencing. So I changed the line
cout << tag1.getContains().getNum() << endl << (*tag1.contains).getNum() << endl;
to
cout << tag1.getContains().getNum() << endl << (*tag1.contains).num << endl;
and I get the output
2
2
Wait, what? I get it if the second line changes from the address to the actual number 2, but why do BOTH change to 2?
setContains makes contains point to a local variable. The variable is destroyed as soon as the function returns, leaving contains a dangling pointer. Any attempt to use it then exhibits undefined behavior.
Practically speaking, contains->num reads some random garbage from the stack where the variable used to live. Slight perturbations to the program change stack access patterns, leaving different garbage there.
Because you'are invoking undefined behavior, you save the address of a local argument to Tag* contains here:
void setContains(Tag t) { contains = &t; }
You should pass the argument by reference or pointer directly. Otherwise you are just saving the address of a variable on stack which is destroyed at function exit.
Everything based on contains afterwards is just undefined behavior.

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.

How can you access private string variables using member functions?

I want to output the values of the private class members Bankcode and AgentName. How can I do this from within my main() function, or in general, outside of the BOURNE class.
My initial code attempts are below:
#include <iostream>
#include <string>
using namespace std;
class BOURNE
{
string Bankcode ={"THE SECRET CODE IS 00071712014"} ; /*private by default*/
string AgentName={"Jason Bourne"}; /*private by default*/
public:
void tryToGetSecretCodeandName(string theName ,string theCode); //trying to get the private
void trytoGetAgentName( string name); // try to get name
};
//***********************defining member function**************************************
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode) //member defining function
{
Bankcode=theCode; //equalling name to the code here
AgentName=theName; //the samething here
cout<<theCode<<"\n"<<theName; //printing out the values
}
//************************main function*****************************
int main()
{
BOURNE justAnyObject; //making an object to the class
justAnyObject.tryToGetSecretCodeandName();
return 0;
}
Third Answer
Your code has two 'getter' style functions, but neither one takes no arguments. That is, both of your functions require arguments to be passed.
Your main function is calling get...CodeandName(), which has no arguments. As such, you get a compiler error, probably complaining about valid signatures, or arguments passed.
Edited Answer
If you only want to get the values, the typical (as far as I am aware) implementation is something like
std::string BOURNE::getCode()
{
return Bankcode;
}
std::string BOURNE::getName()
{
return AgentName;
}
int main()
{
BOURNE myAgent;
cout<< "The agent's name is : " << myAgent.getName() << endl;
cout<< "The agent's code is : " << myAgent.getCode() << endl;
}
Original Answer, left in because I feel like it's more useful
I suspect what you're asking is if you could do something like
void BOURNE::tryToGetSecretCodeandName(string theName, string theCode)
{
if (Bankcode == theCode) {
cout<< "You correctly guessed the code : " << Bankcode << endl;
}
if (AgentName == theName) {
cout << "You correctly guessed the agent's name : " << AgentName << endl;
}
}
This will allow you to repeatedly guess at the name, and get output when you're correct.
If you wanted to disable this kind of guessing, then you could consider creating a new class (possibly derived from/based on std::string - but see this question for reasons to be careful!) and implement an operator== function which always returned false.