I just started working with C++ and am working on an exercise that deals with polymorphic pointers. I'm having trouble trying to solve an error message I believe I'm getting from my Rectangle.cpp as I call the class from my main.cpp.
The error message:
undefined reference to 'Rectangle::Rectangle(double, double)'
Main.cpp
#include <iostream>
#include "Rectangle.h"
using namespace std;
//////////////////////////////////////////////
// --- FUNCTIONS DECLARATION---
void introduceShape(Shape*);
double calculateShapeArea(Shape*);
double calculateShapeCircumferece(Shape*);
int main()
{
Rectangle rectangle1(5,2);
// Rectangle *rec1 = new Rectangle(5,2);
introduceShape(&rectangle1);
cout << "My area is: " << calculateShapeArea(&rectangle1) << ", my circumference is: " << calculateShapeCircumferece(&rectangle1) << endl << endl;
return 0;
}
//////////////////////////////////////////////
// --- FUNCTIONS ---
void introduceShape(Shape* shapeToIntroduce)
{
return shapeToIntroduce->introduce();
}
double calculateShapeArea(Shape* shapeToCalculate)
{
return shapeToCalculate->calculateArea();
}
double calculateShapeCircumferece(Shape* shapeToCalculate)
{
return shapeToCalculate->calculateCircumference();
}
Rectangle.h
#ifndef RECTANGLE_H_INCLUDED
#define RECTANGLE_H_INCLUDED
#include "Shape.h"
#include <iostream>
using namespace std;
class Rectangle: public Shape
{
double width;
double height;
public:
Rectangle(double , double );
void introduce();
double calculateArea();
double calculateCircumference();
};
#endif // RECTANGLE_H_INCLUDED
Rectangle.cpp
#include "Rectangle.h"
#include <iostream>
using namespace std;
Rectangle::Rectangle(double width, double height)
{
this->width = width;
this->height = height;
}
void Rectangle::introduce()
{
cout << "I AM A RECTANGLE !" << endl;
}
double Rectangle::calculateArea()
{
return width*height;
}
double Rectangle::calculateCircumference()
{
return 2*(width+height);
}
Shape.h
#ifndef SHAPE_H_INCLUDED
#define SHAPE_H_INCLUDED
class Shape
{
public:
virtual void introduce() = 0;
virtual double calculateArea() = 0;
virtual double calculateCircumference() = 0;
};
#endif // SHAPE_H_INCLUDED
The error is generated by the linker because it can not see where the definition of the constructor is located.
If you are using an IDE, you should add .cpp file to the project so that it can be compiled and the definition would be found by the linker. It not, then you have to compile it yourself -assuming you are using gcc:
g++ Rectangle.cpp
will combine cpp files into one executable and should not show you that error.
Visit this post
Related
I'm doing the following problem :
Add on to your Rectangle class from last time:
1)Create a new class TestRect which is a friend class of Rectangle. Inside this class, implement a member function called TestRect::tester, which takes a rectangle as a parameter and tests that both length and width are > 0.
2)Create a main() function which makes three rectangles r1, r2, and r3, each of which has length and width 20. Then call your TestRect::tester function on each of these rectangles and print out the result
I think I did part 1) correctly but part 2) does not give me the output I'm looking for. I do not know how to fix my code from the following output I got :
cppcompile rectEnhanceStaticFriends
Undefined symbols for architecture x86_64:
"TestRect::tester(Rectangle&)", referenced from:
_main in rectEnhanceStaticFriends.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
cppcompile:15: no such file or directory: ./rectEnhanceStaticFriends
Can you help me how to fix it? Seems a linker issue, that I did not find how to fix it. Thank you for reading through. (Ps: I compile with VSC)
Here is my code :
rectEnhanceStaticFriends.cpp
#include <iomanip>
#include <cstring>
#include <string>
#include "rect.h"
using namespace std;
int main()
{
Rectangle::setYards(100);
Rectangle r1(20, 20, "Kitchen");
Rectangle r2(20, 20, "Bathroom");
Rectangle r3(20, 20, "Office");
TestRect tr;
cout << "Test on r1: " << tr.tester(r1) << endl;
cout << "Test on r2: " << tr.tester(r2) << endl;
cout << "Test on r3: " << tr.tester(r3) << endl;
Rectangle house[] = {Rectangle(10, 12, "Kitchen"),
Rectangle(20, 20, "Bedroom"),
Rectangle(8, 12, "Offce")};
for (int i = 0; i < 3; i++)
{
if (strcmp(house[i].printName(), "Offce") == 0)
{
// cout << "oui\n";
house[i].setName("Office");
};
cout << "Area for " << house[i].printName() << " is : " << house[i].getArea() << endl;
}
if (house[1].getArea() > house[2].getArea() && house[1].getArea() > house[3].getArea())
{
cout << house[1].printName() << " has the biggest area.\n";
}
else if (house[2].getArea() > house[1].getArea() && house[2].getArea() > house[3].getArea())
{
cout << house[2].printName() << " has the biggest area\n";
}
else
{
cout << house[3].printName() << " has the biggest area\n";
}
//there is an error house[3] go beyond the array..
return 0;
}
testRect.h
#ifndef TESTRECT_H
#define TESTRECT_H
class Rectangle; //forward declaration of class Rectangle
class TestRect
{
public:
bool tester(Rectangle &);
};
#endif
testRect.cpp
#include <iostream> //
#include <iomanip>
#include <string>
#include "testRect.h"
#include "rect.h"
bool TestRect::tester(Rectangle &r)
{
bool testResult = false;
if (r.width > 0 && r.length > 0)
testResult = true;
return testResult;
}
rect.h
// Rec header file
#ifndef RECT_H
#define RECT_H
#include "testRect.h"
class Rectangle
{
private:
double width;
double length;
char *name;
static double yardsAvail; //indicate how many yards of perimeter are available to make rectangle
void initName(const char *n);
void initName(const char *n, int size);
public:
//constructors
Rectangle();
Rectangle(double, double,
const char *);
//destructor
~Rectangle() { delete[] name; };
void setWidth(double);
void setLength(double);
void setWidth(char *);
void setLength(char *);
void setName(const char *);
int getWidth() const;
int getLength() const;
double getArea() const;
char *printName() const
{
return name;
}
//added parts
static void setYards(double);
friend class TestRect;
friend bool TestRect::tester(Rectangle &);
};
double Rectangle::yardsAvail = 0; //added parts
#endif
rect.cpp
#include <iostream> //
#include <iomanip>
#include <string>
#include "rect.h"
#include "testRect.h"
using namespace std;
Rectangle::Rectangle()
{
width = 0;
length = 0;
initName("Default");
}
Rectangle::Rectangle(double x, double y, const char *z)
{
width = x;
length = y;
initName(z);
double yardsReqd = 2 * x + 2 * y;
if (yardsAvail - yardsReqd < 0)
{
cout << "Not enough yard..\n";
width = 0;
length = 0;
}
yardsAvail -= yardsReqd;
}
void Rectangle::initName(const char *n)
{
name = new char[258];
strcpy(name, n);
};
void Rectangle::initName(const char *n, int size)
{
name = new char[size];
strcpy(name, n);
};
void Rectangle::setWidth(double w)
{
width = w;
}
void Rectangle::setLength(double l)
{
length = l;
}
void Rectangle::setName(const char *newname)
{
//newname.newName = "Office";
strcpy(name, newname);
}
double Rectangle::getArea() const
{
return width * length;
}
//added part
void Rectangle::setYards(double y)
{
yardsAvail = y;
}
I am a beginner and running into the above-said error. The following is the complete code from three files:
ball.h:
#ifndef BALL_H
#define BALL_H
namespace
{
inline constexpr double gravity{ 9.81 };
}
double getInitialHeight(void);
double calculateHeight(double, int);
void printHeight(double, int);
void calculateAndPrintHeight(double, int);
void solve(void);
#endif
ball.cpp:
#include "ball.h"
#include <iostream>
double getInitialHeight()
{
std::cout << "Enter the height of the tower in meters ";
double initialHeight{};
std::cin >> initialHeight;
return initialHeight;
}
double calculateHeight(double initialHeight, int secondsPassed)
{
double distanceFallen{ BALL_H::gravity * secondsPassed * secondsPassed / 2.0 };
double currentHeight{ initialHeight - distanceFallen };
return currentHeight;
}
void printHeight(double height, int secondsPassed)
{
if (height > 0.0)
{
std::cout << "At " << secondsPassed << " seconds, the ball is at height\t" << height << " meters.\n";
}
else
{
std::cout << "At " << secondsPassed << " seconds, the ball is on the ground.\n";
std::exit(0);
}
}
void calculateAndPrintHeight(double initialHeight, int secondsPassed)
{
double height{ calculateHeight(initialHeight, secondsPassed) };
printHeight(height, secondsPassed);
}
void solve()
{
const double initialHeight{ getInitialHeight() };
int secondsPassed{ 0 };
while (true)
{
calculateAndPrintHeight(initialHeight, secondsPassed);
secondsPassed++;
}
}
Solution.cpp(the main project file in the solution):
#include <iostream>
#include "ball.h"
int main()
{
solve();
return 0;
}
I understand that this problem is caused because linker cannot find a reference to solve(). However, I am not sure how to solve the issue. One easy solution is to simply include ball.cpp rather than ball.h:
#include <iostream>
#include "ball.cpp"
int main()
{
solve();
return 0;
}
This code works but I'd like to know how to use headers instead since I am not sure if this a good practice.
EDIT:
Here's the error list:
When you add header file, you could right click Header Files and select Add->New Item.
When you add .cpp file, you could right click Source Files and select Add->New Item.
Then, add the following code in Source.cpp.
#include <iostream>
#include "ball.h"
int main()
{
solve();
return 0;
}
Finally, it works fine.
I am a novice at C++. I have started writing a rather large code on a project and I want to make a good base for that. I get the following error when running in Visual Studio:
Exception thrown: read access violation. this was nullptr. occurred
After searching similar questions, I could not find the solution for my code. The error is occurring in Driver.cpp at:
m_setup->SetEquation(...)
Any help is really appreciated. I also appreciate if you have suggestion to improve my code structure.
Main.h:
#ifndef FEM_AD1D_MAIN_H
#define FEM_AD1D_MAIN_H
namespace FEM_AD1D
{
class Driver;
Driver* m_driver;
}
#endif
Main.cpp:
#include "Main.h"
#include "Driver.h"
#include <iostream>
using namespace FEM_AD1D;
int main()
{
std::cout << "Hello World!\n";
m_driver->Run();
}
Driver.h:
#ifndef FEM_AD1D_DRIVER_H
#define FEM_AD1D_DRIVER_H
namespace FEM_AD1D
{
class Setup;
class Driver
{
public:
Driver(Setup* setup);
void Run();
void PreProc();
private:
Setup* m_setup;
const int m_nDim = 1;
const double m_aCoef = 1.0;
const double m_bCoef = 3.0;
const double m_cCoef = 0.0;
const double m_fCoef = 1.0;
const double m_xMin = 0.0;
const double m_xMax = 1.0;
const int m_nElem = 5;
const int m_elemType = 2;
const double m_meshStretch = 0.0;
const int m_nGaussPoint = 3;
};
}
#endif
Driver.cpp:
#include "Driver.h"
#include "Setup.h"
#include <iostream>
#include <array>
using namespace FEM_AD1D;
Driver::Driver(Setup* setup)
{
m_setup = setup;
//m_setup = new Setup();
}
void Driver::Run()
{
PreProc();
}
void Driver::PreProc()
{
std::cout << "Hello World 2!\n";
m_setup->SetEquation(m_nDim, m_aCoef, m_bCoef, m_cCoef, m_fCoef);
}
Setup.h:
#ifndef FEM_AD1D_SETUP_H
#define FEM_AD1D_SETUP_H
#include <vector>
namespace FEM_AD1D
{
class Setup
{
public:
Setup();
void SetEquation(int nDim, double aCoef, double bCoef, double cCoef, double fCoef);
private:
int m_nDim;
double m_aCoef;
double m_bCoef;
double m_cCoef;
double m_fCoef;
};
}
#endif
Setup.cpp:
#include "Setup.h"
#include "Driver.h"
#include <iostream>
#include <vector>
using namespace FEM_AD1D;
Setup::Setup() :
m_nDim(0),
m_aCoef(0.0),
m_bCoef(0.0),
m_cCoef(0.0),
m_fCoef(0.0)
{
}
void Setup::SetEquation(int nDim, double aCoef, double bCoef, double cCoef, double fCoef)
{
// Set the coefficients of the equation
std::cout << "Hello World 3!\n";
m_nDim = nDim;
m_aCoef = aCoef;
m_bCoef = bCoef;
m_cCoef = cCoef;
m_fCoef = fCoef;
}
I'm trying to create a small program for a lessons.
But In My class that herit , I don't have values of the superclass.
, here's the code
Point.h
#ifndef Point_H
#define Point_H
#include <iostream>
class Point{
public:
Point();
void set_values (int a, int b);
void set_values (int a, int b, int c);
void affichervaleurs();
protected:
int x ;
int y ;
int z ;
};
#endif
Point.cpp
#include <iostream>
#include "Point.h"
using namespace std;
Point::Point(){
x=0;
y=0;
z=0;
};
void Point::set_values (int a, int b){
x=a;
y=b;
}
void Point::set_values (int a = 0, int b = 0, int c = 0){
x=a;
y=b;
z=c;
}
void Point::affichervaleurs(){
cout << "X = " << x << endl;
cout << "Y = " << y << endl;
}
Carre.h
#ifndef Carre_H
#define Carre_H
#include "Point.h"
class Carre:public Point{
public:
int Aire (){
};
void affichercar(){
};
};
#endif
Carre.cpp
#include <iostream>
using namespace std;
#include "Point.h"
class Carre:public Point{
public:
//Carre::Carre(int a, int b);
int Aire (){
return (x * y);
}
void affichercar(){
cout << "Coordonnees X:" << x << endl;
}
};
main.cpp
#include <cstdlib>
#include <iostream>
#include "Carre.h"
#include "Point.h"
using namespace std;
int main()
{
Point MonPoint ;
cout << "Default values:" << endl;
MonPoint.affichervaleurs();
MonPoint.set_values(4,6);
cout << "Setting values:" << endl;
MonPoint.affichervaleurs();
Carre MonCarre;
MonCarre.set_values(4,6,0);
MonCarre.set_values(5,8);
MonCarre.affichercar();
cout << MonCarre.Aire() << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
The problem is, when I call this line :
cout << MonCarre.Aire() << endl;
it returns a strange number. I'm sure that the problem is here :
int Aire (){
return (x * y);
};
Like the x and y are not linked with the superclass.
Can someone help me how to access my x and y values from my superclass in my class Carre ?
Other strange thing this line doesn't appear :
MonCarre.affichercar();
Thanks
You define the functions Aire and affichercar in Carre.h, but you need to declare them only if you want to write an implementation in Carre.cpp.
Edit: and your Carre.cpp is also wrong. You just need to rewrite Carre.* files.
Edit2. Let me do some code review and give you a working version of your code - just summarizing what was discussed in comments and my own thoughts.
Point.h
void set_values (int a, int b);
void set_values (int a, int b, int c);
If you want to define the default values of the arguments of the second function, you should do it in its declaration as was suggested in comments to your question. So it will be
void set_values (int a, int b);
void set_values (int a = 0, int b = 0, int c = 0);
But in this case it's not clear what function should be called if you write, for example, set_values(1, 2), therefore your code won't compile because of ambiguity (as also was mentioned in the comments). So you just have to keep only one extended version of this function with the default arguments. The Point.h will be in this case:
#ifndef Point_H
#define Point_H
#include <iostream>
class Point{
public:
Point();
void set_values (int a = 0, int b = 0, int c = 0);
void affichervaleurs();
protected:
int x ;
int y ;
int z ;
};
#endif
The Point.cpp is also changed a little bit:
#include <iostream>
#include "Point.h"
using namespace std;
Point::Point()
// it's better to initialize these variables here
// : x(0), y(0), z(0)
{
x=0;
y=0;
z=0;
}
void Point::set_values (int a, int b, int c){
x=a;
y=b;
z=c;
}
void Point::affichervaleurs(){
cout << "X = " << x << endl;
cout << "Y = " << y << endl;
}
Now let's consider the Carre.h file
class Carre:public Point{
public:
// IT'S DEFINITION WHICH IS USED WHEN YOU CALL THE FUNCTION
int Aire (){};
// IT'S DEFINITION WHICH IS USED WHEN YOU CALL THE FUNCTION
void affichercar(){};
};
Now I'm starting answering your questions:
The problem is, when I call this line :
cout << MonCarre.Aire() << endl;
it returns a strange number.
Yes, it's a strange number returned by the function defined in the Carre.h (not Carre.cpp) file.
I'm sure that the problem is here :
int Aire (){
return (x * y);
};
No, as you see, it's not.
Like the x and y are not linked with the superclass.
In fact they are.
Can someone help me how to access my x and y values from my superclass in my class Carre ?
You already have this access. It's okay to use protected members from base class in derived class in case of public inheritance.
Other strange thing this line doesn't appear : MonCarre.affichercar();
You mean it does nothing? But it's in perfect consistency with how you implement (define) the function in Carre.h (not Carre.cpp) file.
So let me change the code to make it work.
Carre.h
#ifndef Carre_H
#define Carre_H
#include "Point.h"
class Carre:public Point{
public:
int Aire (); // now it's declaration
void affichercar(); // now it's declaration
};
#endif
Carre.cpp
#include <iostream>
using namespace std;
int Carre::Aire (){
return (x * y);
}
void Carre::affichercar(){
cout << "Coordonnees X:" << x << endl;
}
I didn't compile this for myself, but the whole idea should be clear.
access my x and y values
From within Carre, you simply access them by 'x' and 'y'.
From outside, you cannot as they are not public.
I am practicing class declaration/implementation/passing object by reference. Here is my code for my main class, header file, and other class:
//Header file (Circle2.h)
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle{
private:
double radius;
public:
Circle();
Circle(double newRadius);
double getArea() const;
double getRadius() const;
void setRadius(double newRadius);
};
#endif
//Main class (PassObjectByReference.cpp)
#include <iostream>
#include "Circle2.h"
using namespace std;
void printCircle(const Circle &c){
cout << "The area of the circle of " << c.getRadius() << " is " << c.getArea() << endl;
}
int main(){
Circle myCircle(5.0);
printCircle(&myCircle);
return 0;
}
//Other class (Circle2.cpp)
#include "Circle2.h"
Circle::Circle(){
radius = 1;
}
Circle::Circle(double newRadius){
radius = (newRadius >= 0) ? newRadius : 0;
}
double Circle::getRadius() const{
return radius;
}
double Circle::getArea() const{
return radius * radius * 3.14159;
}
void Circle::setRadius(double newRadius){
radius = (newRadius >= 0) ? newRadius : 0;
}
When I try to compile, I get these two errors:
PassObjectByReference.cpp: In function ‘int main()’:
PassObjectByReference.cpp:11: error: invalid initialization of reference of type ‘const Circle&’ from expression of type ‘Circle*’
PassObjectByReference.cpp:5: error: in passing argument 1 of ‘void printCircle(const Circle&)’
I can't find the error. Any help would be greatly appreciated.
Thank you!
int main(){
Circle myCircle(5.0);
printCircle(&myCircle); // You are passing a pointer.
return 0;
}
The correct statement is:
printCircle(myCircle);
Drop the & - that's turning it into a pointer, which is not what you want. You should just write:
printCircle( myCircle );