Having trouble with objects and classes in C++ - c++

So, I defined the method displayStudInfo in the 'Student' Class and called it in the main function. But I'm getting the error "Function not declared in this scope". Can anyone please tell me why this is happening and what I can do to solve this problem?
#include <iostream>
#include <string>
using namespace std;
class Student{
public:
int age;
string name;
void enterInfo(){
cout << "Enter your age = " ; cin >> age;
cout << "Enter your name = "; cin >> name;
}
void displayStudInfo(Student s)
{
cout << "Age = " << s.age << ", name=" << s.name << endl;
}
};
int main(){
int size;
Student stud[100];
Student abir;
abir.enterInfo();
displayStudInfo(abir);
}

In your case void displayStudInfo(Student s) is a member function of Student so you have to call it on an instance of Student, the same way you did with enterInfo.
You can solve that in different ways. One way is to make that member function a free function by moving it out of the body of the Student
class Student{
public:
// … 
};
void displayStudInfo(Student s)
{
cout << "Age = " << s.age << ", name=" << s.name << endl;
}
int main(){
// … 
displayStudInfo(abir);
}
displayStudInfo is, in fact, a good candidate for a free function. Or you make it static which is similar to a free function, and access the static member function using Student::displayStudInfo(abir).
The other way would be to call displayStudInfo on abir in that case you don't need the Student argument, as abir is implicitly passed to displayStudInfo.
class Student{
public:
// … 
void displayStudInfo()
{
cout << "Age = " << age << ", name=" << name << endl;
}
};
int main(){
// … 
abir.displayStudInfo();
}

void displayStudInfo(Student s) hidden in side class.
So, its not accessible in main().
Try:
void displayStudInfo()
{
cout << "Age = " << age << ", name=" << name << endl;
}
call in main():
abir.displayStudInfo();

In C++, all member functions implicitly receive a parameter which points to the current object. This parameter is the this pointer.
Therefore, it doesn't make sense for you to specify an additional (explicit) parameter for the object in your definition of the function displayStudInfo.
It would make sense to rewrite the function definition to
void displayStudInfo()
{
cout << "Age = " << age << ", name=" << name << endl;
}
and to call it with
abir.displayStudInfo();
instead of
displayStudInfo(abir);
Alternatively, you could make the function displayStudInfo a non-member function, by putting it outside the declaration of class Student. In that case, you would have to keep the explicit parameter, because that parameter is only passed implicitly to member functions.

Related

Passing an object to a method CPP C++

I'm still learning C++ so go easy on me.
Is there a way I can pass an object to a method without specifying an object? I'm probably butchering the terms so ill show code.
class Student
{private:
std::string Name;
float GPA;
char Sex;
int Absentee;
int *Data ;
public:
std::string GetName();
float GetGPA();
char GetSex();
int GetAbsentee();
void SetData(int);
int GetData();
int *GetDataAddr();
//Methods
void DisplayStudent(Student);
void Student::DisplayStudent(Student Stud)
{
std::cout << "___________________________________" << std::endl;
std::cout << "Name :" << Stud.GetName() << std::endl;
std::cout << "GPA :" << Stud.GetGPA() << std::endl;
std::cout << "Sex :" << Stud.GetSex() << std::endl;
std::cout << "Absentee :" << Stud.GetAbsentee() << std::endl;
std::cout << "Data :" << Stud.GetData() << std::endl;
std::cout << "Data Add :" << Stud.GetDataAddr() << std::endl;
std::cout << "___________________________________" << std::endl;
}
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
* Compiles fine: Spike.DisplayStudent(Spike);
* DOSNT Compile: Student DisplayStudent(Spike);
* C++ a nonstatic member reference must be relative to a specific object*
return 0;
}
So the question I have is at least with this method, why do I need to specify or rather, what is the purpose of "Spike" in "Spike.DisplayStudent(.....)"? Student::Display(.....) makes far more sense to me.
If your Student::DisplayStudent is designed to display information for the student who is represented by that class instance, you don't need to pass Student Stud at all, just use member variables.
If however it is designed to display info for ANY student - you can make it a static member, or a free-standing function.
If you want the member function DisplayStudent to display the information for the very instance of Student on which the function is called, you do not need to pass a Student as an argument.
class Student {
public:
// The getter methods should be `const`, since calling them does not change
// the `Student`:
const std::string& GetName() const; // return a `const&` to avoid unecessary copying
void DisplayStudent() const; // No `Student` argument, like in `GetName()`
// ...
};
void Student::DisplayStudent() const {
std::cout << "___________________________________\n"
"Name :" << GetName() << "\n"
"GPA :" << GetGPA() << "\n"
"Sex :" << GetSex() << "\n"
"Absentee :" << GetAbsentee() << "\n"
"Data :" << GetData() << "\n"
"Data Add :" << GetDataAddr() << "\n"
"___________________________________\n";
}
You also do not need to call getter methods in DisplayStudent() since you have access to the private member variables and do not need to do any calculations before returning the result.
Usage example (if the appropriate constructor exists as you've indicated):
int main() {
Student Spike("Spike", 3.9f, 'M', 43,55);
Spike.DisplayStudent(); // no instance passed as an argument
}

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.

No match for "operator<<" in std::operator

#include <iostream>
#include <string>
using namespace std;
// your code
class Dog {
public:
int age;
string name, race, voice;
Dog(int new_age,string new_name,string new_race,string new_voice);
void PrintInformation();
void Bark();
};
Dog::Dog(int new_age,string new_name,string new_race,string new_voice) {
age = new_age;
name = new_name;
race = new_race;
voice = new_voice;
}
void Dog::PrintInformation() {
cout << "Name: " << name;
cout << "\nAge: " << age;
cout << "\nRace: " << race << endl;
}
void Dog::Bark(){
cout << voice << endl;
}
int main()
{
Dog buffy(2, "Buffy", "Bulldog", "Hau!!!");
buffy.PrintInformation();
cout << "Dog says: " << buffy.Bark();
}
I'm newbie in C++ and I'm unable to figure out the error.I am getting the error at buffy.Bark(),it seems like its unable to print something which returns void.
no match for operator<< in std::operator<< >(&std::cout),((const char)
Either declare member function Bark like
std::string Dog::Bark(){
return voice;
}
and call it like
cout << "Dog says: " << buffy.Bark() << endl;
Or do not change the function but call it like
cout << "Dog says: ";
buffy.Bark();
because the function has return type void.
Or take another dog from the dog kennel.:)
Bark is defined as a void function:
void Dog::Bark(){
cout << voice << endl;
}
This means that trying to do cout << buffy.Bark() in main is trying to cout a void type variable, which is not possible. It's likely you simply meant buffy.Bark();, which will already output for you.

struct output with cout, and function call struct parameters

So, the problem is several errors at compile time.
ReadMovieData(string* title, string* director) cannot convert from movieInfo to string*
DisplayMovieData(string title, string director) cannot convert from movieInfo to string
No operator found which takes a right-hand operand of type 'movieInfo' (or there is no acceptable conversion.
The bottom error happens twice in DisplayMovieData() so I wrote it once for simplicity sake.
The ReadMovieData function should accept a structure pointer reference variable and the DisplayMovieData function should accept a MovieInfo structure variable.
The main function creates an array of 2 MovieInfo struct variables and the other functions should be called on an element of the array.
The code I have finished is below.
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
//prototypes
int ReadMovieData(string* title, string* director);
int DisplayMovieData(string title, string director);
struct movieInfo {
string title, director;
};
int main(){
const int SIZE = 2;
movieInfo movieList[SIZE];
movieInfo movie;
//supposed to assign data to movieList[i] at some point
for (int i = 0; i < SIZE; i++){
ReadMovieData(movie, movie);
DisplayMovieData(movie, movie);
}
return 0;
}
int ReadMovieData(movieInfo &title, movieInfo &director){
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return 0;
}
int DisplayMovieData(movieInfo title, movieInfo director){
cout << "The movie name is: " << title << endl;
cout << "The director of " << title << " is: " << director << endl;
return 0;
}
There are mismatches between your function prototypes and their definitions, as you can see comparing the parameter types in both.
Note that since you defined a structure for the movie info, you can directly pass it to the reading and displaying functions (instead of passing the single structure data member strings).
You may want to read the following compilable code:
#include <iostream>
#include <string>
using namespace std;
struct MovieInfo {
string title;
string director;
};
void ReadMovieData(MovieInfo& movie);
void DisplayMovieData(const MovieInfo& movie);
int main() {
const int SIZE = 2;
MovieInfo movieList[SIZE];
for (int i = 0; i < SIZE; i++) {
ReadMovieData(movieList[i]);
DisplayMovieData(movieList[i]);
}
}
// Since movie is an output parameter in this case, pass by non-const reference.
void ReadMovieData(MovieInfo& movie) {
//get the movie name
cout << "What is the movie? ";
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin >> movie.director;
}
// Since movie is an input parameter in this case, pass by reference to const.
void DisplayMovieData(const MovieInfo& movie) {
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title
<< " is: " << movie.director << endl;
}
The errors are pretty explanatory and clear - your function takes string* but you're passing movieInfo - unrelated types can't just magicaly convert one to another.
What you probably want is pass the data members of movieInfo:
ReadMovieData(&movie.title, &movie.director);
It would be better if arguments were not pointers - use references instead. Where you won't be changing the arguments, the references should be to const type.
Even better, why not just pass moveInfo
ReadMovieData(movieInfo& movie);
and let the function deal with the internals of the class? This better encapsulates data and doesn't lead to spaghetti code quite so fast.
Also, the declarations and definitions need to match (otherwise you'd be overloading) - you're using pointers in some places and references/values in others.
Finally, here's how an overload of operator<< might look like:
std::ostream& operator<<(std::ostream& os, const movieInfo& m)
{
return os << "Title: " << m.title << ", Director: " << m.director;
}
Your class movieInfo does not have an overloaded << operator, which is necessary is you want to work with iostream, however, you can pass the strings contained in movieInfo:
int DisplayMovieData(string &title, string &director) { }
Call like:
DisplayMovieData(movie.title, movie.director);
You are declaring the function with this signature
int ReadMovieData(string* title, string* director);
but you're defining it using
int ReadMovieData(movieInfo &title, movieInfo &director) {
// ...
}
These don't match!
The code is totally invalid. I suppose the valid code should look the following way
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
struct movieInfo
{
string title, director;
};
//prototypes
movieInfo ReadMovieData();
void DisplayMovieData( const movieInfo & );
int main()
{
const int SIZE = 2;
movieInfo movieList[SIZE];
//supposed to assign data to movieList[i] at some point
for ( int i = 0; i < SIZE; i++ )
{
movieList[i] = ReadMovieData();
DisplayMovieData( movieList[i] );
}
return 0;
}
movieInfo ReadMovieData()
{
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return movie;
}
void DisplayMovieData( const movieInfo &movie )
{
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title << " is: " << movie.director << endl;
}

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;
}