No suitable constructor to convert from int to emp - c++

My program simply is to increase the salary int the emp class throw the the function increase
but I'm having this error int the call function line from the line :
No suitable constructor to convert from int to emp
here 's my code :
#include <iostream>
#include <string>
using namespace std;
class emp
{
public:
int salary;
};
void increase(emp x,emp y)
{
x.salary+=100;
y.salary+=250;
}
int main()
{
int value=0;
emp fst, scnd;
cin >> fst.salary >> scnd.salary;
increase(fst.salary,scnd.salary);
cout << fst.salary << endl << scnd.salary << endl;
cin >> value;
return 0;
}

increase expects two emps as parameters, yet you pass in two ints.
Change
increase(fst.salary,scnd.salary);
to
increase(fst,scnd);
Your next question is going to be why the values don't change, so to save you the trouble - it's because you're passing by value, effectively changing copies of your original objects. You'll need to pass by reference:
void increase(emp& x,emp& y)

increase(fst.salary,scnd.salary); should be increase(fst,scnd);, void increase(emp x,emp y) ... should be void increase(emp& x,emp& y) ...

You need to pass emp not int. Further, you are passing parameters by value. Use this instead:
void increase(emp &x,emp &y)
And pass the struct variables; i.e. fst and scnd instead of fst.salary and scnd.salary. Refer this question for better understanding.

Related

Is there a way to pass user data for a setter without using an extra variable in C++?

I'm still new to C++ and so far I used to pass static values to setter methods. Now I'm trying to pass user data to the methods, but so far I can only do this using an extra variable as follows.
Class:
class Square
{
private:
double length;
public:
void setLength(double l);
double getlength();
double calcArea();
};
In main function:
Square s1;
double x;
cout << "Enter length: ";
cin >> x;
s1.setLength(x);
Thus, I use a temporary variable to pass user values to setters.
My question is, is there a way to directly pass variables to the setter? or is there a better way?
Please note that I am a beginner in C++, therefor please be descriptive and simple. Thanks!!
I don't think it's a good idea but this works :
#include <iostream>
using std::cout;
using std::cin;
class Square
{
private:
double len;
public:
double& length() {return len;}
double length() const {return len;}
};
int main() {
Square s1;
cout << "Enter length: ";
cin >> s1.length();
cout << "length: " << s1.length();
}
you can do like this
#include<iostream>
class Square
{
private:
double length;
friend std::istream& operator>>(std::istream&,Square& );
public:
void setLength(double l);
double getlength();
double calcArea();
};
std::istream& operator>>(std::istream& is, Square& s )
{
is>>s.length;
return is;
}
int main()
{
Square s;
std::cout<<"Enter length: ";
std::cin>>s;
}
It should be a design question. Does being able to load directly a specific attribute from a stream make sense? If it has a semantic value (it makes sense at the business object level) or helps to follow the DRY (do not repeat yourself) princip by avoiding code duplication, then you should write a specific method:
class Square {
private:
double length;
...
public:
std::istream& loadlength(istream& in) {
in >> length;
return in;
}
...
You can then use it easily:
s1.loadlength(std::cin);
if (! std::cin) {
// process the error condition
....
You can either set the value using a variable or you can send a value, but the thing is that if you want to do it directly, it will break the law of Encapsulation. We can the class attributes private to make sure of Encapsulation. So for that, the thing you did is perfect ✌🏻.

How to freeze a variable since it first assigned?

Please assume the version of gcc 7.2.1 in this question
I would like to declare a global variable which behave like a const however, the value to initialize it cannot not be detected before the program being executed. In other words, the target variable would be re-assigned since the first time it is assigned.
An ugly approach of this concept as follow:
#include<iostream>
int numberOfPeople; //Do not re-assign it after it first assign
int main(){
std::cin >> numberOfPeople; // Do not re-assign numberOfPeople since then !!!
// Following of codes omitted.
}
As you could see, this is a very ugly approach and cannot be checked by compiler. I wonder whether there is a kind of notation in c++ that can freeze the variable since it first assigned.
So I can write code like this:
#include<iostream>
magic_notation int numberOfPeople;
int main(){
std::cin >> numberOfPeople; // Allowed as it's first assign.
// Median codes omitted.
numberOfPeople = 60. //Disallowed and will get an error message from compiler!
// Following codes omitted.
}
Is there any kind of notation as can use like the magic_notation in the code above in c++?
The best approach is to make a class with a public const member variable which gets initialized in the constructor:
struct InitInfo {
const int numberOfPeople;
InitInfo() numberOfPeople(getNumberOfPeople()) {
}
private:
static int getNumberOfPeople() {
int res;
cin >> res;
return res;
}
};
InitInfo initInfo;
Now you can use the member variable as follows:
int main() {
cout << initInfo.numberOfPeople << endl;
}
You can use the same approach for initializing a global variable, too.
static int getNumberOfPeople() {
int res;
cin >> res;
return res;
}
const int numberOfPeople = getNumberOfPeople();
int main() {
cout << numberOfPeople << endl;
numberOfPeople += 10; // <<== This triggers an error
}
One approach you can use is to wrap the variable as a static variable in a function. Use the function instead of the variable in rest of your code.
#include <iostream>
int readFromStdin()
{
int n;
cin >> n;
return n;
}
// Wrap it arund in a function.
// int numberOfPeople; //Do not re-assign it after it first assign
int getNumberOfPeople()
{
// Initialize by reading from stdin.
static int numberOfPeople = readFromStdin();
returnn numberOfPeople;
}
int main(){
// Use the function instead of the variable.
getNumberOfPeople();
}
In case you have different ways to initialize the variable, you could come up with something like this:
struct {
int value() const { return _val; }
void init(int val) {
if(!_set) _val = val;
}
private:
int _val;
bool _set = false;
} numberOfPeople;
Now, everybody who uses the variable should call init before using it to make sure it is initialized.

Dynamicly setting which parameter to extract

Having structure
struct Person{
Person(int a , int i):age(a),id(i){};
int age;
int id;
}
Is it possible to pass which argument to exctract as argument in function? Something like
int extract( Person * p , param ){
return p -> param;
}
which would return id , if used it like
extract( p , "id" )
and age if i used it like
exctract(p , "age")
Is something like this possible in c++?
You can use pointers to class members.
struct Person{
Person(int a , int i):age(a),id(i){};
int age;
int id;
};
int extract(Person* p, int Person::* param)
{
return p->*param;
}
and you'd use it like this:
extract(p, &Person::id);
demo
You can do it with preprocessor abuse, and more notably, without using string comparisons, which seems like what you want to do.
#include <iostream>
#define extract(p, i) (p->i)
struct Person{
int age;
int id;
};
int main() {
Person p;
p.age = 100;
p.id = 30;
std::cout << extract((&p), id) << '\n' << extract((&p), age) << '\n';
}
Not that I suggest doing this, though.
You can use Map<char*, int>which can do exactly that (but arguably is a bit of owerkill).
Or just plain char[][] and check equality with the parameter in a for loop.

c++ char array output in class functions

I am a real c++ beginner and I have a problem with my char array output in a c++ excerise. I was asked to transform a certain UML class in to c++ and generate an working output with the parameters given in main. Here ist the code:
#include <iostream>
#include <stdlib.h>
/*My class defintion book*/
class Book
{ protected:
long int number;
char author[25];
int year;
bool lent;
void setLent(bool x);
bool getLent();
public:
Book(long int n, char a[25], int j, bool x);
long int getNr();
int getYear();
void print();
};
/*Method definition Book*/
Book::Book(long int n, char a[25], int j, bool x)
{number=n;
author=a;
year=j;
lent=x;}
long int Book::getNr()
{return number; }
int Book::getYear()
{return year;}
void Book::setLent(bool x)
{lent=x;}
bool Book::getLent()
{return lent;}
void Book::print()
{
std::cout << "Book Nr: " << number << std::endl;
std::cout << "Author: " << author << std::endl;
std::cout << "Year: " << year << std::endl;
if (lent==0)
std::cout << "Lent [yes/no]: no" << std::endl;
else
std::cout << "Lent [yes/no]: yes" << std::endl;
}
/*MAIN*/
int main()
{
Book b1(123456, "test", 2014, false);
b1.print();
system("pause");
return 0;
This is my output:
Book Nr: 123456
Author: b<Vv-[[vóYA
Year: 2014
Lent [yes/no]: no
Press any key to continue...
As you can see all outputs work except for the "Author". There I am getting crap. Note that I have to use char as type. since it is given in the UML class I had to transform into c++.
I really searched everywhere. But didn't find the correct solution. I have the feeling it will be a very simple one...
Thanks in advance for your help!
The reason this doesn't work is that you're assigning your pointer author to another pointer a, which then goes out of scope... so you're left with author pointing to some garbage. If you want to stick with character arrays, you'll have to copy all the data that a points to:
strcpy(author, a);
But since it's C++, you should just use strings, which are easier to deal with:
class Book {
...
std::string author;
....
};
Book::Book(long int n, const std::string& a, int j, bool x)
: author(a), ...
{ }
You are printing out uninitialized data.
Make author a string
#include <string>
class Book
{ protected:
long int number;
std::string author;
int year;
bool lent;
and make the argument to the constructor a string as well
Book::Book(long int n, const std::string& a, int j, bool x)
Arrays of characters are not as flexible as std::strings. they are just chunks of data. If you want to use strings then use std::string instead.
Also, use an initializer list in C++ constructors, not java style
Book::Book(long int n, const std::string &a, int j, bool x)
: number(n),
author(a),
year(j),
lent(x)
{ }
There are two bugs in your code:
Book::Book(long int n, const char a[25], int j, bool x)
{
number=n;
strncpy(author, a, 25); // author = a; doesn't work! shouldn't compile either...
year=j;
lent=x;
}
First: The variable author is a pointer to a zero terminated string. You can use strcpy() to copy this string. Therefore you need to #include <memory.h. But you need to be sure that the string -is- really zero-terminated and fits into your target variable! Else you'll overwrite other memory regions next to the target variable, which is also called a buffer overflow! Better use strncpy(target, source, maxlength); which avoids this problem.
Second: Your parameter a should be "const" as you want to be able to call it with a string constant like in Book b1(123456, "test", 2014, false); where "test" is a constant!
As others already suggested you should use std::string instead of a[25]. C-Strings are "C" and not "C++" and you should try to avoid them. C-Strings can introduce a lot of bugs into your code and enable buffer overflows (=security problems), too. Also they are more complicated to handle. You need to #include <string> to use them.

Char passing in C++ with pointers

Im having unclear image of pointers and char passing with functions. please anyone can tell me where im doing wrong and brief idea about pointers?ex : where should i use them, etc...
#include <iostream>
using namespace std;
class book{
private:
char *CName;
int CFee;
int NoPeople;
int Income;
public:
void setData(char &x,int y,int z){
CName = &x;
CFee = y;
NoPeople = z;
}
void calIncome(){
Income = CFee * NoPeople;
}
void viewIncome(){
cout<<Income;
cout<<CName;
}
};
int main(){
book b1;
b1.setData('DISE',20000,30);
b1.calIncome();
b1.viewIncome();
}
im getting error in this code
//b1.setData('DISE',20000,30); "non-const lvalue reference to type 'char' cannot bind to a temparory of type 'int'"
In your code there is no need for pointers. You should use std::string:
#include <string>
...
string CName
...
void setData(const string& x,int y,int z){
CName = x;
and in setData call you should use double quotes (which are for strings) instead of single quotes (which are for individual characters).
You should change setData() declaration to void setData(const char *x,int y,int z)
As you're currently doing you are expecting a reference to a single char as parameter, which cannot be used to assign a char* pointer that is meant to point at a character array.
Also you aren't specifying a character array literal in the call:
b1.setData('DISE',20000,30);
Needs to be changed to
b1.setData("DISE",20000,30);
// ^ ^
b1.setData('DISE',20000,30);
char is only one char, like 'D', if you have multiple char, that is string, and you need to pass it as "DISE"
With your method signature, void setData(char &x,int y,int z) you can only pass char. That is one character.
setData metod is completely useless here. Its work should be done by a constructor, and the name variable (which should NOT be named CName should be an std::string. viewIncome should automatically call calIncome and a dirty flag should probably be introduced. Otherwise calIncome should be a free/static function and the income member should be removed. The function parameters should also be reasonably captioned.
And I'll even answer the question:
class Book {
std::string name;
int fee;
int noPeople;
int income;
public:
Book(std::string name, int fee, int noPeople) :
name(std::move(name)),
fee(fee),
noPeople(noPeople)
{
}
void calIncome() {
income = fee * noPeople;
}
void viewIncome() {
calIncome();
std:: cout << income << name;
}
};
int main() {
Book b1 ("DISE", 20000, 30);
b1.viewIncome();
}
See it live on Coliru.