I cannot use the static variable [duplicate] - c++

This question already has answers here:
Undefined reference to a static member
(5 answers)
Closed 1 year ago.
I'm trying to print the employee count after each created object but I'm getting an error like this: undefined reference to `Employee::numberofEmployees'. How can I solve this little problem? Any ideas? Btw I'm using a local class.
the purpose of the numberofEmployees variable is to store the information on the number of employee objects created/instantiated so far.
#include <iostream>
#include <string>
using namespace std;
class Employee{
public:
string name;
string surname;
int year;
double salary;
static int numberofEmployees;
Employee(int yil,string isim,string soyisim): year(yil),name(isim),surname(soyisim){
numberofEmployees++;
}
Employee(){
name = "not-set";
year = 0;
surname = "not-set";
salary = 0.0;
}
void calculateSalary(){
salary = 2310 + 2310 * year * 12 / 100.0;
}
void printInfo(){
cout << name << " " << surname << " " << "(" << year << ")" << " " << salary << "TL/month" << endl;
}
};
int main()
{
Employee person1(4,"Berk","Kandemir");
cout << Employee::numberofEmployees << endl;
Employee person2(8,"Esat","Kandemir");
cout << Employee::numberofEmployees << endl;
Employee person3(20,"Paul","Walker");
cout << Employee::numberofEmployees << endl;
person1.calculateSalary();
person2.calculateSalary();
person3.calculateSalary();
person1.printInfo();
person2.printInfo();
person3.printInfo();
return 0;
}

You have to initialize your static data member outside the class using scope resolution operator something like this.
int Employee::numberofEmployees = 0;
This shows that you are accessing a static variable of class Employee and then initializing it.

If you have a static variable within a class, you are supposed to initialise it outside of the class, ie in a .cpp file. From C++17, however, you are allowed to initialise it in-class, in-line, using the inline keyword.
Code:
#include <string>
#include <iostream>
using namespace std;
class Employee
{
public:
string name;
string surname;
int year;
double salary;
static inline int numberofEmployees = 0;
Employee(int yil, string isim, string soyisim) : year(yil), name(isim), surname(soyisim)
{
numberofEmployees++;
}
Employee()
{
name = "not-set";
year = 0;
surname = "not-set";
salary = 0.0;
}
void calculateSalary()
{
salary = 2310 + 2310 * year * 12 / 100.0;
}
void printInfo()
{
cout << name << " " << surname << " "
<< "(" << year << ")"
<< " " << salary << "TL/month" << endl;
}
};
int main()
{
Employee person1(4, "Berk", "Kandemir");
cout << Employee::numberofEmployees << endl;
Employee person2(8, "Esat", "Kandemir");
cout << Employee::numberofEmployees << endl;
Employee person3(20, "Paul", "Walker");
cout << Employee::numberofEmployees << endl;
person1.calculateSalary();
person2.calculateSalary();
person3.calculateSalary();
person1.printInfo();
person2.printInfo();
person3.printInfo();
return 0;
}
Or keep your code and add:
int Employee::numberofEmployees = 0;
After your class.
Output:
1
2
3
Berk Kandemir (4) 3418.8TL/month
Esat Kandemir (8) 4527.6TL/month
Paul Walker (20) 7854TL/month

Related

Why do I get the error "use of deleted function 'class : : class()"

#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob;
ob.marks();
ob.display();
ob.calc();
}
I've been asked to use parameterized constructors to do this problem and notice I get these errors when I use constructors. Sorry if this post is inconvenient to read. In what way can I run this code while creating objects from parameterized constructors?
use of deleted function 'result::result()'
use of deleted function 'test::test()'.
no matching function for call to 'student::student()'
no matching function for call to 'sports::sports()'
student and sports have user-defined constructors, so the compiler does not generate default constructors for them.
test and result have no user-defined constructors, so the compiler will generate default constructors for them. However, since student and sports have no default constructors, the generated default constructors are marked delete'd as they are not usable. That is why you get errors.
To make your main() compile as-is, you need to define your own default constructors for test and result which pass explicit parameter values to their base classes, eg:
#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
test() : student("", 0, 0) {}
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
result() : test(), sports(0) {}
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob;
ob.marks();
ob.display();
ob.calc();
}
Online Demo
However, this is not very useful, so I would suggest tweaking result's constructor to take the student and sports objects you have already created beforehand, and pass them to the base class copy constructors, which the compiler will generate for you, eg:
#include <iostream>
using namespace std;
class student
{
protected:
string name;
int roll;
int age;
public:
student(string n, int r, int a)
{
name = n;
roll = r;
age = a;
}
};
class test : public student
{
protected:
int sub[5];
public:
test(const student &s) : student(s) {}
void marks()
{
cout << "Enter marks in 5 subjects: " << endl;
cin >> sub[0] >> sub[1] >> sub[2] >> sub[3] >> sub[4];
}
void display()
{
cout << "Name : " << name << "\nRoll number : " << roll << "\nAge: " << age << endl;
cout << "Marks in 5 subjects : " << sub[0] << ", " << sub[1] << ", " << sub[2] << ", " << sub[3] << ", " << sub[4] << endl;
}
};
class sports
{
protected:
int sportmarks;
public:
sports(int sm)
{
sportmarks = sm;
}
};
class result : public test, public sports
{
int tot;
float perc;
public:
result(const student &s, const sports &sp) : test(s), sports(sp) {}
void calc()
{
tot = sportmarks;
for(int i = 0; i < 5; i++)
tot = tot + sub[i];
perc = (tot / 600.0) * 100;
cout << "Total: " << tot << "\nPercentage: " << perc << endl;
}
};
int main()
{
student ob1("Name", 781, 19);
sports ob2(78);
result ob(ob1, ob2);
ob.marks();
ob.display();
ob.calc();
}
Online Demo

private static variable accesing output is linker issues [duplicate]

This question already has answers here:
Undefined reference to static variable c++
(3 answers)
Closed 2 years ago.
I created a Class Student with instance data members
like studentname, studentaddress, studentrollno
i declared private static data member CollegeName that could be shared among all instances of class.
used promptfunction to take user input from the console
next functions to display student details.
Meanwhile resulting in below errors :
Meanwhile codes goes here:
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
int studentrollno;
string studentName;
string studentAddress;
static string CollegeName;
public:
void setRollNo(int rollno) {
studentrollno = rollno;
}
int getRollNo() {
return studentrollno;
}
void setName(string name) {
studentName = name;
}
string getName() {
return studentName;
}
void setAddress(string address) {
studentAddress = address;
}
string getAddress() {
return studentAddress;
}
static void setCollegeName(string collegename) {
CollegeName = collegename;
}
static string getCollegeName() {
return CollegeName;
}
void displayStudentDetails(); // member functions declare inside class Meanwhile it is defined
outside
static void show() {
cout << "this is static function " << endl;
}
};
// member functions define outside Student class
void Student :: displayStudentDetails() {
cout << "Student Name : " << getName() << " Student RollNo : " << getRollNo() << "Student Address
: " << getAddress() << "CollegeName: "<< getCollegeName() << endl;
}
void promptValues(Student &student) {
cout << "Enter the student Details " << endl;
cout << "Enter the details about student objects " << endl;
cout << endl;
int studentrollno;
string studentname , studentaddress ;
string collegename;
cout << "Enter the RollNo of the student " << endl;
cin >> studentrollno;
cout << "Enter the Name of the student " << endl;
cin >> studentname;
cout << endl;
cout << "Enter the address of the student " << endl;
cin >> studentaddress;
cout << endl;
cout << "Enter the collegeName of the student " << endl;
cin >> collegename;
student.setRollNo(studentrollno), student.setName(studentname), student.setAddress(studentaddress),
student.setCollegeName(collegename);
}
int main() {
Student student1, student2 , student3 , student4 , student5 ;
Student studentarrays[5] = { student1, student2, student3, student4, student5 };
Student studentmodel[5];
for (int i = 0; i < 5; i++) {
Student model;
model = studentarrays[i];
promptValues(model);
studentmodel[i] = model;
}
for (Student studentdetails : studentmodel) {
studentdetails.displayStudentDetails();
}
Student::show();
return 0;
}
You have omited the definition of the static member Student::CollegeName. It is only declared in the class, now you should define it after the class declaration with this:
std::string Student::CollegeName;
For more information see https://en.cppreference.com/w/cpp/language/static

Can anyone help me how to call this function parameter from class to be displayed in my output

This coding where I used function overloading is a code where user have to input their pointer for 4 subjects and its credit hour so it prints out their GPA. The thing is I have 3 parameter in Student(string test123, string nama, string vinto ). But I only want to display either one of the string. Lets say I want the Vinto to be print out. How can I call the vinto in my Display function so that it prints out Vinto. Heres's My coding.
CPP.cpp
#include <iostream>
#include "student.h"
using namespace std;
void main(void)
{
string nama;
string test123;
int i;
Student StudentA(test123, nama, "vinto");
cout << "key in points for 4 subject\n";
StudentA.Getpointers();
StudentA.Display(test123);
}
Student.h
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
Student(string test123, string nama, string vinto );
void Getpointers();
void Display(string name);
private:
double points[4];
int creditHours[4];
string name;
double CalculateGPA();
};
Student.cpp
#include <iostream>
#include <iomanip>
#include<string>
#include "student.h"
using namespace std;
Student::Student(string test123, string nama, string vinto)
{
name = nama;
}
void Student::Getpointers()
{
for (int i = 0; i<4; i++)
{
cout << "points for subject :" << i + 1 << endl;
cin >> points[i];
cout << "credit hour for subject " << i + 1 << endl;
cin >> creditHours[i];
}
}
void Student::Display(string name)
{
cout << "Hello " << name << endl;
cout << "Your current GPA is " << setprecision(3) << CalculateGPA() << endl;
}
double Student::CalculateGPA()
{
double totalpoints = 0;
int totalcreditHours = 0;
for (int i = 0; i<4; i++)
{
totalpoints += (points[i] * creditHours[i]);
totalcreditHours += creditHours[i];
}
return totalpoints / totalcreditHours;
}
Well, the vinto argument of your constructor is not saved anywhere, so in this example you cannot get it back. However, you could store it:
First, add a vinto field to the class:
class Student
{
public:
Student(string test123, string nama, string vinto );
void Getpointers();
void Display(string name);
private:
double points[4];
int creditHours[4];
string name;
string vinto;
double CalculateGPA();
};
Then, store the vinto argument value in this field:
Student::Student(string test123, string nama, string vinto)
{
name = nama;
this->vinto = vinto;
}
After this, you may use vinto:
void Student::Display(string name)
{
cout << "Hello " << name << endl;
cout << "Your current GPA is " << setprecision(3) << CalculateGPA() << endl;
cout << "Your vinto is " << vinto << endl;
}
Also, it's a bit strange that you store student's name in the object field, but use another name (which is passed to Student::Display) to say Hello to him.

arry of pointers ( classes )

So I have these classes:
In main I wrote an array of pointers:
student *arry[10];
How can I make each cell point to an object of a different class?
For example :
I want the cell 0 , 2 , 4
point to an object of class medstudent
using ( new statement )
thank you
here is class medStudent
#include<iostream>
#include"student.cpp"
using namespace std;
class medStudent:public student {
public :int clinicH;
public:
medStudent(int ch, string n , int i ):student(n,i){
setClinicH(ch);
cout << "New Medecine Student" << endl;
}
~medStudent(){
cout << "Medecine Student Deleted" << endl;
}
medStudent(medStudent & ms):student(ms){
cout << "New Copy Medecined Student" << endl;
}
medstudent(){
}
void setClinicH(int ch){
clinicH = ch;
}
int getClinicH()const{
return clinicH;
}
void print()const{
student::print();
cout << "Clinical Hours: " << getClinicH() << endl;
}
};
Here is class student:
#include <iostream>
//#include"medstudent.cpp"
using namespace std;
class student//:public medstudent
{
public :
static int numberOfSaeeds;
const int id;
string name;
public:
~student(){
cout << "Delete Student: " << getName() << " " << endl ;
}
student(string n, int i):id(i){
setName(n);
cout << "Student with args" << endl ;
}
void setName(string n){
name = n;
}
string getName()const{
return name;
}
void print()const{
cout << "My name is: " << name << endl;
cout << "My ID is: " << id << endl;
}
void setNOS(int nos){
numberOfSaeeds = nos;
}
int getNOS(){
return numberOfSaeeds;
}
void printAddress()const{
cout << "My address is " << this << endl;
}
student * getAddress(){
return this;
}
student(student & sc):id(sc.id){
name = sc.name;
setName(sc.getName());
cout << "New Object using the copy constructor" << endl;
}
};
Here is main code:
#include<iostream>
using namespace std;
#include"time.cpp"
#include "student.cpp"
//#include"medstudent.cpp"
int main(){
student a1("asa" , 2);
student * a[10];
a[3]= new student("jj", 22 );
a[0] = new medStudent();
}
Since you explicitly declare a medStudent constructor the compiler will not create a default constructor for your class. And when you do new medStudent(); you are (explicitly) trying to invoke the default constructor, which doesn't exist.
That will give you a build error, one that should have been very easy to diagnose if you read it and most importantly shown it to us (when asking questions about build errors, always include the complete and unedited error output, including any informational output, in the body of the question, together with the code causing the error).
The solution? Call the existing parameterized constructor. E.g. new medStudent("foo", 123).
By the way, if you want inheritance to work okay, and the base-class destructor to be called when deleting an object of a child-class, then you need to make the destructors virtual.

error: ISO C++ forbids in-class initialization of non-const static member

this is the header file: employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <iostream>
#include <string>
using namespace std;
class Employee {
public:
Employee(const string &first, const string &last)
Overloaded Constructor
: firstName(first),
firstName overloaded constructor
lastName(last)
lastName overloaded constructor
{ //The constructor start
++counter;
it adds one plus per each object created;
cout << "Employee constructor for " << firstName
<< ' ' << lastName << " called." << endl;
}
~Employee() {
Destructor
cout << "~Employee() called for " << firstName << ' '
<< lastName << endl;
Returns the first and last name of each object
--counter;
Counter minus one
}
string getFirstName() const {
return firstName;
}
string getLastName() const {
return lastName;
}
static int getCount() {
return counter;
}
private:
string firstName;
string lastName;
static int counter = 0;
Here is where i got the error. But, why?
};
principal program: employee2.cpp
#include <iostream>
#include "employee2.h"
using namespace std;
int main()
{
cout << "Number of employees before instantiation of any objects is "
<< Employee::getCount() << endl;
Here ir call te counter's value from the class
{
Start a new scope block
Employee e1("Susan", "Bkaer");
Initialize the e1 object from Employee class
Employee e2("Robert", "Jones");
Initialize the e2 object from Employee class
cout << "Number of employees after objects are instantiated is"
<< Employee::getCount();
cout << "\n\nEmployee 1: " << e1.getFirstName() << " " << e1.getLastName()
<< "\nEmployee 2: " << e2.getFirstName() << " " << e2.getLastName()
<< "\n\n";
}
end the scope block
cout << "\nNUmber of employees after objects are deleted is "
<< Employee::getCount() << endl; //shows the counter's value
} //End of Main
What is the problem?
I have no idea what's wrong.
I have been thinking a lot, but a i do not what is wrong.
The initialization of the static member counter must not be in the header file.
Change the line in the header file to
static int counter;
And add the following line to your employee.cpp:
int Employee::counter = 0;
Reason is that putting such an initialization in the header file would duplicate the initialization code in every place where the header is included.
According to a similar SO answer there is another approach, in particular suited for your current implementation (header-only library):
// file "Employee.h"
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee {
public:
Employee() {
getCounter()++;
}
~Employee() {
getCounter()--;
}
static auto getCount() -> std::size_t {
return getCounter();
}
private:
// replace counter static field in class context,
// with counter static variable in function context
static auto getCounter() -> std::size_t& {
static std::size_t counter = 0;
return counter;
}
};
#endif //EMPLOYEE_H
I took the liberty to use std::size for representing the non-negative employee count and trailing return syntax for functions.
Accompanying test (ideone link):
#include "Employee.h"
int main() {
std::cout << "Initial employee count = " << Employee::getCount() << std::endl;
// printed "count = 0"
Employee emp1 {};
std::cout << "Count after an employee created = " << Employee::getCount() << std::endl;
// printed "count = 1"
{
Employee emp2 {};
std::cout << "Count after another employee created = " << Employee::getCount() << std::endl;
// printed "count = 2"
}
std::cout << "Count after an employee removed = " << Employee::getCount() << std::endl;
// printed "count = 1"
return 0;
}