Undefined reference to Class::Class/Function (Beginner in OOP) - c++

I have this annoying error;
Undefined Reference to Shape::Shape(...), Shape::getName(...), Shape::getAge(...)
My Main.cpp is this
#include <iostream>
#include <string>
#include "Bit.h"
using namespace std;
int main()
{
//simple assignment
string name;
int age;
cout<<"enter name: ";
cin>>name;
cout<<"enter age: ";
cin>>age;
Shape sh(name,age); //class declaration (i think here is the problem)
cout<<endl<<"name: "<<sh.getName();
cout<<endl<<"age: "<<sh.getAge();
return 0;
}
This is the Bit.h header
#include <iostream>
#include <string>
using namespace std;
#ifndef BIT_H
#define BIT_H
//creating class
class Shape{
string newName;
int newAge;
public:
//Default Constructor
Shape();
//Overload Constructor
Shape(string n,int a);
//Destructor
~Shape();
//Accessor Functions
string getName();
int getAge();
};
And finally, this is the Bit.cpp
#include "Bit.h"
//constructors and destructor
Shape::Shape(){
newName="";
newAge=0;
}
Shape::Shape(string n, int a){
newName=name;
newAge=age;
}
Shape::~Shape(){
}
string Shape::getName(){
return newName;
}
//getters
int Shape::getAge(){
return newAge;
}
I understand, that this might be a very simple problem/error, but I have been struggling for about 2 hours.
I suppose that the error is in the declaration od "sh" object, even if I declare it like this "Shape sh();" or "Shape sh;", there are still errors.
Thanks
EDIT. GNU GCC Compiler
EDIT2. Using Code Blocks (sorry for forgetting all these)

You're probably not compiling Bit.cpp, but only Main.cpp.
Considering that Bit.h, Bit.cpp and Main.cpp are in the same folder, here is how you should compile it :
g++ *.cpp
It will still not compile, as in the default constructor, you're trying to initialize name, and age which both don't exist.
You probably meant newAge, and newName?
In the other Constructor, name and age also don't exist, you probably meant n, and a?

Related

Getting class type redefinition and a few other errors

I'm creating a student data management console application for a project. I created a class called Student which is storing all the data that a student needs to have, and it also has all the getters and setters associated with it. Here is how all my files are laid out:
Student.h
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
string id;
string email;
int presentation;
int essay1;
int essay2;
int project;
public:
//constructor
//Student();
//setters
void set_name(string);
void set_id(string);
void set_email(string);
void set_presentation(int);
void set_essay1(int);
void set_essay2(int);
void set_project(int);
//getters
string get_name();
string get_id();
string get_email();
int get_presentation();
int get_essay1();
int get_essay2();
int get_project();
};
Student.cpp
#include <iostream>
#include <string>
#include "Student.h"
using namespace std;
//constructor definition
/*
Student::Student(void) {
cout << "Student created" << endl;
}
*/
//setter definition
void Student::set_name(string s) {
name = s;
}
void Student::set_id(string s) {
id = s;
}
void Student::set_email(string s) {
email = s;
}
void Student::set_presentation(int a) {
presentation = a;
}
void Student::set_essay1(int a) {
essay1 = a;
}
void Student::set_essay2(int a) {
essay2 = a;
}
void Student::set_project(int a) {
project = a;
}
//getter definition
string Student::get_name() {
return name;
}
string Student::get_id() {
return id;
}
string Student::get_email() {
return email;
}
int Student::get_presentation() {
return presentation;
}
int Student::get_essay1() {
return essay1;
}
int Student::get_essay2() {
return essay2;
}
int Student::get_project() {
return project;
}
Main.cpp
#include <iostream>
#include <string>
#include "Student.h"
using namespace std;
int main() {
cout << "Hello World!" << endl;
Student student1;
Student student2;
Student student3;
student1.set_name("John");
student2.set_name("Bob");
student3.set_name("Carl");
return 0;
}
When I try to run my program, I get, amongst others, the following errors:
Error 1 error C2011: 'Student' : 'class' type redefinition
Error 2 error C2079: 'student1' uses undefined class 'Student'
Error 5 error C2228: left of '.set_name' must have class/struct/union
Error 9 error C2027: use of undefined type 'Student'
How can I go about fixing this issue?
I'm quite sure this is an error caused by the fact that student.h is included twice in a certain .cpp file. Thus you need to use so-called header guards to make sure the file is only included once in every .cpp file:
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student {
/* ... */
};
#endif
The idea behind this is that an #include is a preprocessor directive that results in the argument file being copied into the file where the #include was issued. Hence, if files A and B include Student.h, and file C includes both files A and B, then the declaration of class Student is going to end up duplicated. Hence the error. The above macros make sure that this doesn't happen.
Edit as per the question author's comment:
#pragma once is the same as #ifndef .. #define #endif but non-standard .
See #pragma once vs include guards? for reference.
I had the same error. I just clean and rebuild the solution and error resolved.

Inheritance in C++?

I'm trying to learn about inheritance. I've tried to make a class called ProductionWorker that is derived from Employee. I'm trying to follow the model given by this website. However, it seems like the inheritance isn't working because I get errors in the main function saying that name, number, and date are not set in this scope. What is wrong with the code?
Program.cpp:
#include <iostream>
#include <string>
#include "employee.h"
using namespace std;
int main() {
ProductionWorker worker;
cout<<"What is the employee name?"<<endl;
cin>>name;
worker.setName(name);
cout<<"What is the employee number?"<<endl;
cin>>number;
worker.setNumber(number);
cout<<"What is the employee hire date?"<<endl;
cin>>date;
worker.setDate(date);
cout<<"Employee Information:"<<endl;
cout<<worker.getName()<<endl;
cout<<worker.getNumber()<<endl;
cout<<worker.getDate()<<endl;
cout<<worker.getShift()<<endl;
cout<<worker.getPayRate()<<endl;
return 0;
}
employee.h:
#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_
#include <string>
#include <iostream>
using namespace std;
class Employee{
protected:
string name;
int number;
string date;
public:
Employee(string a="", int b=0, string c=""){
name=a;
number=b;
date=c;
}
void setName(string);
void setNumber(int);
void setDate(string);
string getName();
int getNumber();
string getDate();
};
class ProductionWorker: public Employee{
private:
int shift;
double pay;
public:
ProductionWorker(int d=1, double e=10.0, string a="", int b=0, string c=""):Employee(a, b, c){
shift=d;
pay=e;
}
int getShift();
double getPayRate();
};
employee.cpp:
#include <string>
#include <iostream>
#include "employee.h"
using namespace std;
//EMPLOYEE
void Employee::setName(string a){
name=a;
}
void Employee::setNumber(int b){
number=b;
}
void Employee::setDate(string c){
date=c;
}
string Employee::getName(){
return name;
}
int Employee::getNumber(){
return number;
}
string Employee::getDate(){
return date;
}
//PRODUCTION WORKER
int ProductionWorker::getShift(){
return shift;
}
double ProductionWorker::getPayRate(){
return pay;
}
I think that you should declare name, number and date before you use it, in Program.cpp. You try to get input into symbol that compiler doesn't know yet.
Your error is nothing to do with inheritance:
int main() {
ProductionWorker worker;
cout<<"What is the employee name?"<<endl;
cin>>name;
You're reading into a variable called name but no such variable is in scope (i.e. declared in the main() function itself or globally). Though name is a member of the Employee class, you cannot use it as such in this way. (Consider: how would the compiler know which instance of Employee that you were wanting to set the name of? And, of course, if you could read directly into the instance variable, there would be no need to call worker.setName(...) afterwards).
You should just declare name as a local variable, by specifying its type:
int main() {
string name;
ProductionWorker worker;
cout<<"What is the employee name?"<<endl;
cin>>name;
Now cin>>name; reads into the local variable name that is declared within the main() function. (I took the liberty of fixing your indentation). In a similar way, you need declarations for date and number.
You haven't declared the variables that cin needs to read into.
Just add
string name;
int number;
string date;
At the top of function main.

c++ undefined refernce to class constructer

//Header FILE:
#ifndef BMI_H_INCLUDED
#define BMI_H_INCLUDED
#include<iostream>
#include<string>
using namespace std;
class BMI{
public:
//default constructer
BMI();
//overloaded
BMI(string,int,double);
private:
string newName;
int newHeight;
double newWeight;
};
#endif // BMI_H_INCLUDED
//Implementation file:
#include "BMI.h"
BMI ::BMI(){
newHeight=0;
newWeight=0.0;
}
BMI::BMI(string name,intheight,double weight){
newName=name;
newHeight=height;
newWeight=weight;
}
//Main file:
#include <iostream>
#include<string>
#include "BMI.h"
using namespace std;
int main()
{
string name;
int height;
double weight;
cout<<"Name:\n";
getline(cin,name);
cout<<"Height(Inches):\n";
cin>>height;
cout<<"Weight(Pounds):";
cin>>weight;
BMI person_1("John",89,90.0);
//I get the error on the above line error is //undefinedreferenceto`BMI::BMI(std::string, int, double)'
}
Does anyone have any idea why this keeps happening to me?
I use Codeblocks and if so how can I fix this and prevent it from happening again.
This happens every time I separate classes into headers and cpp files. This is just one of the many times my program fails to compile due to this.
in BMI::BMI(string name,intheight,double weight){ theres no space between int and height.
This causes BMI person_1("John",89,90.0); to refer to a constructor that doesn't exist.

C++ Object inaccessible

I'm trying to reference an object in a function and it is giving me an "Object is inaccessible" error. Here is the header and cpp file in question.
customer header file below. I've put the object declaration at the bottom.
#pragma once
#include "bankAccount.h"
#include "checkingAccount.h"
#include "savingsAccount.h"
#include "address.h"
using namespace std;
class customer {
public:
customer(void);
customer(string,string);
~customer(void);
void setName(string n);
string getName();
void withdrawChecking(double);
void wihdrawSavings(double);
double depositSavings(double);
string print();
private:
string name
checkingAccount myChecking;
savingsAccount mySavings;
};
Here is the cpp file. I've bolded the problem statement.
#include "customer.h"
#include "checkingAccount.h"
customer::customer(void){
}
customer::customer(string n, string ac){
name = n;
mySavings.setAccount(ac);
myChecking.setAccount(ac);
}
void customer::setName(string n){
name = n;
}
string customer::getName(){
return name;
}
void withdrawChecking(double w){
myChecking.withdrawChecking(w);
}
So what is wrong with this last statement and my header?
Sorry for bad styling... first time posting a question.
You're missing a customer on the front of withdrawChecking. It should be:
void customer::withdrawChecking(double w)

Defining a vector within a custom class

I'm trying to simply use a vector within one of my classes. When trying to access the vector it tells me that it's undefined (but I've defined it in my header).
I have two classes, Person and Dog. A person can own one or more dogs so I want to add each dog a person owns into an array. This should be real simple so this problem is really starting to get to me. Here's some code:
The class Person.cpp:
#include "Person.h"
#include "stdafx.h"
#include <iostream>
using namespace std;
Person::Person(string name, string address, int age)
:name(name),
address(address),
age(age)
{}
int Person::getAge(){
return age;
}
std::string Person::getDogInfo(int index){
}
void Person::addDog(string dogName, string breed){
dogCollection.push_back(Dog(dogName, breed));
}
std::vector<Dog> getDogs(){
return dogCollection; //dogCollection undefined error here
}
And here's Person.h:
#ifndef Person_H
#define Person_H
#include <vector>
#include "Dog.h"
using namespace std;
class Person{
public:
Person(string name, string address, int age);
string getName(){return name};
string getAddress(){return address};
void addDog(string dogName, string breed);
string getDogInfo(int index);
std::vector<Dog> getDogs();
int getAge();
private:
string name;
string address;
int age;
std::vector<Dog> dogCollection;
};
#endif
If you want to have a look at my dog classes I'll paste them as well:
Dog.cpp:
#include "stdafx.h"
#include <iostream>
#include "dog.h"
Dog::Dog(string dogName, string breed)
:dogName(dogName),
breed(breed){}
std::string Dog::Dog.getDogName(){
return dogName;
}
std::string Dog::Dog.getBreed(){
return breed;
}
and Dog.h:
#ifndef Dog_H
#define Dog_H
#include <iostream>
using namespace std;
class Dog{
public:
Dog(std::string dogName, std::string breed);
std::string getDogName();
std::string getBreed();
private:
std::string dogName;
std::string breed;
};
#endif
Also, I just want to add that this is no homework. I'm used to java and I'm only trying to learn some C++ since I need it for future work.
EDIT: Updated the code
std::vector<Dog> dogCollection; // here im defining dogCollection, no error here!
There actually is an problem here - class Dog isn't known to the compiler at this point.
You can solve this by either including Dog.h before Person.h in Person.cpp, or better add an #include "Dog.h" at the top of Person.h.
This is incorrect (and unrequired):
dogCollection = new std::vector<Dog>; // Remove this line.
as dogCollection is not a std::vector<Dog>*.
This is also incorrect:
void Person::addDog(string dogName, string breed){
Dog *newDog = new Dog(dogName, breed);
dogCollection.push_back(newDog);
}
as dogCollection contains Dog instances, not Dog*. Change to:
void Person::addDog(string dogName, string breed){
dogCollection.push_back(Dog(dogName, breed));
}
There is a problem with all of constructors:
Person::Person(string name, string address, int age){
name=name;
address=address;
age=age;
}
This is assigning the argument name to itself: it is not assigning to the member name. Same for address and age and similarly for the constructors of the other classes. Use initializer list:
Person::Person(string name, string address, int age) :
name(name),
address(address),
age(age)
{}
This method does not return a std::string:
string Person::getDogInfo(int index){
}
EDIT:
Missing class qualifier:
std::vector<Dog> getDogs(){
return dogCollection; //dogCollection undefined error here
}
means this is just a free function, with no association to class Person and therefore no access to dogCollection.
Change to:
std::vector<Dog> Person::getDogs(){
return dogCollection;
}
There are several problems with your code, and most of the other answers have pointed them out - mostly regarding the use of new when it should not be used. (Are you a C# programmer, moving to C++?)
However, there are problems with the #include directives as well. As #Bo mentioned, since Person uses Dog, you should include that header in Person.h. But Person also uses vector so that header should be included there as well. So Person.h should start with...
#include <vector>
#include "Dog.h"
Then in Person.cpp you don't have to include those files.
As a general rule (you can learn about "forward declaration" later), any types referenced in a header should be #included in that header.