I have created a class name Employee and inside that I have declared a function and two variable(name ,age) . After creating a variable x I am not getting the name insted getting empty name and age =0
CODE:
#include<iostream>
using namespace std;
class Employee{
public:
string name;
int age;
void print(){
cout<<"Name:"<<name<<endl;
cout<<"Age:"<<age<<endl;
}
Employee(string name,int age){
name = name;
age=age;
}
};
int main(){
Employee x=Employee("chang",33);
x.print();
return 0;
}
Expected:
name:Chang
age :33
OutPut:
name:
age :0
Can Someone tell me what is the reason behind it.
Employee(string name, int age) {
name = name;
age = age;
}
you are not modifying the class members, but the parameters instead.
You have three ways to solve this problem:
use this-> to precisely target the right variables.
Employee(string name, int age) {
this->name = name;
this->age = age;
}
use an initialisation list:
Employee(string name, int age) : name(name), age(age) {
}
don't use any constructor, but use brace initialization instead:
int main() {
Employee x = Employee{ "chang", 33 };
x.print();
}
I would personally use option three with the braces, as it's the most efficient to write.
read here why you shouldn't be using namespace std;
Related
I am new to using pointers with c++, so I am trying this small code but the problem is that when i try to print name i get this random weird number \364\277\357\376\326\241+\310\364\277\357\376\310. This is not the memory address, which is confusing and what confuses me more that when i replace name with getName() it works perfectly and prints the name! Thanks you!!
Person.cpp
#include "Pesron.hpp"
#include <string>
#include <iostream>
using namespace std;
Person:: Person()
{
}
Person::Person(string Name, int Age)
{
name=&Name;
age=Age;
}
void Person:: setName(string Name)
{
name=&Name;
}
void Person:: setAge(int Age)
{
age=Age;
}
string Person:: getName()
{
return *name;
}
int Person:: getAge()
{
return age;
}
void Person:: display()
{
cout<<*name<<" "<<age<<" ";
}
Person::~Person()
{
}
Student.cpp
#include "Student.hpp"
Student:: Student(string Name, int Age,int Grades, int ID):Person(Name , Age)
{
grades=Grades;
id=ID;
}
void Student:: setId(int ID)
{
id=ID;
}
int Student:: getId()
{
return id;
}
void Student:: setGrades(int Grades )
{
grades= Grades;
}
int Student:: getGrades()
{
return grades;
}
void Student:: display()
{
Person::display();
cout<<grades<<" "<<id<<endl;
}
main.cpp
#include "Pesron.hpp"
#include "Student.hpp"
#include "graduteStudent.hpp"
#include <iostream>
int main(int argc, const char * argv[]) {
// insert code here...
Student student("ZAID",21,2211,11);
student.display();
return 0;
}
Output
\364\277\357\376\326\241+\310\364\277\357\376\310 21 2211 11
Person::name looks like it is a std::string *. In Person::Person(string Name, int Age) you pass the paramater Name by value and then store the address of this local variable in name. When Name goes out of scope you have a dangling pointer.
(This also applies to void Person::setName(string Name))
Dereferencing Person::name is undefined behaviour, because the object it is pointing doesn't exist anymore. The solution is to simply store a std::string and not just a pointer to it.
So you get something like
class Person {
private:
std::string name;
int age;
public:
Person(std::string Name, int Age) : name(Name), age(Age) {}
};
I am new to this. Basically I just learnt how to use class in C++. When I try to print out, the values just seem to be 0. Can anyone help me out? Its supposed to print out:
Susan Myers 47899 Accounting Vice President
Mark Jones 39119 IT Position
Joy Rogers 81774 Manufacturing Engineer
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Employee
{
private:
string name;
int idNumber;
string department;
string position;
public:
Employee()
{
name=" ";
idNumber=0;
department=" ";
position=" ";
}
Employee(string, int, string, string)
{
int id;
string n,d,p;
name=n;
idNumber=id;
department=d;
position=p;
}
Employee(string, int)
{
string n;
int id;
name=n;
idNumber=id;
}
void setName(string)
{
string n;
name=n;
}
void setId(int)
{
int id;
idNumber=id;
}
void setDepartment(string)
{
string d;
department=d;
}
void setPosition(string)
{
string p;
position=p;
}
string getName() const
{
return name;
}
int getId() const
{
return idNumber;
}
string getDepartment() const
{
return department;
}
string getPosition() const
{
return position;
}
};
int main()
{
Employee e1;
Employee e2;
Employee e3;
e1.setName("Susan Meyers");
e2.setName("Mark Jones");
e3.setName("Joy Rogers");
e1.setId(47899);
e2.setId(39119);
e3.setId(81744);
e1.setDepartment("Accounting");
e2.setDepartment("IT");
e3.setDepartment("Manufacturing");
e1.setPosition("Vice President");
e2.setPosition("Programmer");
e3.setPosition("Engineer");
cout<<"---------------------------------------"<<endl;
cout<<"Name"<<setw(6)<<"ID Number"<<setw(10)<<"Department"<<setw(12)<<"Position"<<endl;
cout<<e1.getName()<<setw(6)<<e1.getId()<<setw(10)<<e1.getDepartment()<<setw(12)<<e1.getDepartment()<<endl;
cout<<e2.getName()<<setw(6)<<e2.getId()<<setw(10)<<e2.getDepartment()<<setw(12)<<e2.getDepartment()<<endl;
cout<<e3.getName()<<setw(6)<<e3.getId()<<setw(10)<<e3.getDepartment()<<setw(12)<<e3.getDepartment()<<endl;
return 0;
}
This is what you get when you rely on guesswork rather than properly reading an introductory textbook on C++
A constructor of the Employee class which (apart from a blank line that I've removed) you define as
Employee(string, int, string, string)
{
int id;
string n,d,p;
name=n;
idNumber=id;
department=d;
position=p;
}
has the following effects.
The four arguments passed by the caller are ignored, since they are not named.
Four default-initialised variables (id, n, d, and p) are defined local to the constructor body. id will be uninitialised. The others, since they are std::string, are default-initialised (to an empty string)
The next four statements copy those variables into class members. The result is that initialising idNumber has undefined behaviour (since id is uninitialised) and the three strings are initialised to empty strings.
To get the effect that (I assume) you intend, change this to;
Employee(std::string n, int id, std::string d, std::string p)
{
name=n;
idNumber=id;
department=d;
position=p;
}
Note that I'm calling string by its full name std::string. That allows removing the using namespace std which (among other things) is BAD practice in header files.
Even better, change this to
Employee(const std::string &n, int id, const std::string &d, const std::string &p) :
name(n), idNumber(id), department(d), position(p)
{
}
which passes the strings by const reference (avoids additional copies of std::strings) and uses an initialiser list instead of assigning to members in the constructor.
Similar comments apply to ALL of the member functions of Employee, except that only constructors can have initialiser lists.
Errors made
Presentation
Your code is extremely cluttered, and has much irrelevant stuff.
Syntax
void setPosition(string){
Here your function has no argument! What is string?
Code
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Employee{
public:
string name;
int idNumber;
string department;
string position;
void setName(string n){
name=n;
}
void setId(int k){
int id;
idNumber=id;
}
void setDepartment(string d){
department=d;
}
void setPosition(string p){
position=p;
}
string getName(){
return name;
}
int getId(){
return idNumber;
}
string getDepartment(){
return department;
}
string getPosition(){
return position;
}
};
int main(){
Employee e1;
Employee e2;
Employee e3;
e1.setName("Susan Meyers");
e2.setName("Mark Jones");
e3.setName("Joy Rogers");
e1.setId(47899);
e2.setId(39119);
e3.setId(81744);
e1.setDepartment("Accounting");
e2.setDepartment("IT");
e3.setDepartment("Manufacturing");
e1.setPosition("Vice President");
e2.setPosition("Programmer");
e3.setPosition("Engineer");
cout<<"---------------------------------------"<<endl;
cout<<"Name"<<" "<<"ID Number"<<" "<<"Department"<<" "<<"Position"<<endl;
cout<<e1.getName()<<" "<<e1.getId()<<" "<<e1.getDepartment()<<" "<<e1.getPosition()<<endl;
cout<<e2.getName()<<" "<<e2.getId()<<" "<<e2.getDepartment()<<" "<<e2.getPosition()<<endl;
cout<<e3.getName()<<" "<<e3.getId()<<" "<<e3.getDepartment()<<" "<<e3.getPosition()<<endl;
}
Output
---------------------------------------
Name ID Number Department Position
Susan Meyers 32767 Accounting Vice President
Mark Jones 32767 IT Programmer
Joy Rogers 32767 Manufacturing Engineer
Explanation
I have shortened your code by 50%(shows how much redundant stuff you had), and here is a working code.
void setDepartment(string d){
department=d;
}
Here, string d is defined IN the function as an argument. Note that your code also cout<< department twice, and I have corrected that for you in my above code.
Hope this helps.
May someone please help me correct the following. I'm trying to wrap my head around how to create a pointer to an existing object within a new object. I can't get the syntax correct and keep getting errors.
Here's my code:
class Country
{
string name;
public:
Country (string name)
{ name = name;
cout << "Country has been created" << endl;}
~Country()
{cout << "Country destroyed \n";}
};
class Person
{
//string name;
//Date dateOfBirth;
Country *pCountry;
public:
Person(Country *c):
pCountry(c)
{}
};
int main()
{
Country US("United States");
Person(&US)
return 0;
}
Did you forget in your main.cpp?
#include <string>
#include <iostream>
using namespace std;
you also need a semicolon in your main:
int main()
{
Country US("United States");
Person person(&US); // < -- variable name and semicolon missing
return 0;
}
You should also change:
Country (string name)
{
this->name = name; // <-- assign name to member variable
...
or better, use member initializer lists:
Country (string name) : name(name) // <-- assign name to member variable
{
...
And in general you should try to be consistent with the way you format your code.
I have just learnt some object oriented programming concepts in Python, but I want to transfer this knowledge to C++, and I have trouble with basic implementation that used to be easy using Python.
#include<iostream>
using namespace std;
class Animal{
char name;
int age;
public:
Animal(char name, int age);
};
Animal::Animal(char name, int age) {
this->name = name;
this->age = age;
}
int main()
{
Animal dog ("Megg", 10);
cout << "Name: " dog.name <<endl;
return 0;
}
When I compile this code, I get a lot of messages, such as:
error: no matching function for call to 'Animal::Animal(const char[5], int)'
note: Animal::Animal(char, int) <near match>
note: candidate expects 1 argument, 2 provided
Thanks!
you don't need to do this->name = name in your constructor definition
"Megg" is a string literal. You can cast "Megg" into const char * but not into a char (this was most likely causing your error).
or better yet. You can use the C++ Standard Library string class std::string
#include <iostream>
#include <string>
class Animal{
std::string name;
int age;
public:
Animal(std::string name, int age);
std::string getName() const;
int getAge() const;
};
Animal::Animal(std::string Name, int Age) {
name = Name;
age = Age;
}
std::string Animal::getName() const {
return name;
}
int Animal::getAge() const {
return age;
}
int main()
{
Animal dog ("Megg", 10);
std::cout << "Name: " << dog.getName() << std::endl; // Error in this line. Missing << between "Name: " and dog.name
return 0;
}
Some additional edits:
You should avoid using using namespace std as it takes everything in the Standard Library (from the files you've included) and puts it in the global namespace. You can instead use the scope resolution operator :: as seen above.
When you start working with multiple libraries you may encounter that both have a class named vector or string, or functions with the same name. The way to avoid this is to specify what namespace you want to use.
or alteratively you can do the following:
using std::cout;
using std::endl;
using std::string;
Additionaly in order for you program to work you need a way to access your object's member variables. You could do this by making the variables public or the better practice is to add accessor functions.
I'm currently working on an assignment to expand on a program we previously made, involving the use of header files, and parent classes. In the original, I have 2 header files. Person.h, and OCCCDate.h. In the new one, I am creating one called OCCCPerson.h. It's an incredibly simple class that basically just uses Person, just with 1 added variable.
My problem is, I cant figure out how to use the parent constructor properly.
Here is the Person.h file.
#ifndef PERSON_H
#define PERSON_H
#include <string>
#include "OCCCDate.h"
using namespace std;
class Person{
private:
string firstName;
string lastName;
OCCCDate dob;
public:
Person();
Person(string, string);
Person(string, string, OCCCDate);
string getFirstName();
string getLastName();
void setFirstName(string);
void setLastName(string);
int getAgeInYears();
bool equals(Person);
string toString();
};
#endif
And here is my OCCCPerson.h file
#ifndef OCCCPERSON_H
#define OCCCPERSON_H
#include <string>
#include "OCCCDate.h"
#include "Perosn.h"
using namespace std;
class OCCCPerson : Person{
protected:
string studentID;
public:
OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID);
OCCCPerson(Person p, string studentID);
string getStudentID();
bool equals(OCCCPerson p);
string toString();
};
#endif;
I cant seem to call on the parents constructor to get things like the firstname, lastname, and dob(date of birth). From my handout, it says the parent constructor has to be initialized with, : Person(parameters), where parameters are things in the parent class. However, I have no idea where to put that. Sorry for writing so much. I just couldn't figure out how to shrink that down.
Oh, and here is OCCCDate.h just in case
#ifndef OCCCDATE_H
#define OCCCDATE_H
#include<string>
using namespace std;
class OCCCDate{
private:
bool OCCCDate_US;
bool OCCCDate_EURO;
int dayOfMonth, monthOfYear, year;
bool dateFormat;
public:
OCCCDate();
OCCCDate(int dayOfMonth, int monthOfYear, int year);
int getDayOfMonth();
int getMonth();
string getNameOfMonth();
int getYear();
string getDate();
int getDifference(OCCCDate d1, OCCCDate d2);
int getDifference(OCCCDate d1);
void setDateFormat(bool);
bool equals(OCCCDate d);
string toString();
};
#endif
And here is my OCCCDate.cpp file
#include<iostream>
#include<ctime>
#include "OCCCPerson.h"
using namespace std;
OCCCPerson::OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID):Person(firstName, lastName, dob){
string firstName = Person::getFirstName();
string lastName = Person::getLastName();
OCCCDate dob = dob;
this->studentID = studentID;
}
OCCCPerson::OCCCPerson(Person p, string studentID){
Person p = p;
this->studentID = studentID;
}
What you need is member initializer lists.
From cppreference:
In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members.
A simple example:
class MyClass : BaseClass
{
public:
MyClass(int arg) : BaseClass(arg) {
//Rest of code
}
}
In your case, you can do:
OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID) :
Person(firstName, lastName, dob) {
this.studentID = studentID;
}
In OCCCPerson.cpp,
OCCCPerson(string firstName, string lastName, OCCCDate dob, string
studentID) : Person(firstName, lastName, dob)
{
//more stuff
}
You basically have to use an initializer list.
Read more here: What are the rules for calling the superclass constructor?
What this does is it calls the parent constructor Person(string, string, OCCCDate) and basically performs this->firstName = firstName. Similarly for lastName and dob. But not studentID because the Person(string, string, OCCCDate) constructor doesn't provide initialization for studentID.