Can't pass a constant object by reference - c++

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

Related

Calculate class Cylinder using class Circle

The constructor of class "Circle" allows the radius to be specified via a parameter, while it is not possible to create objects of the Circle type without specifying the parameter. Also, automatic conversion of real numbers into Circle objects must not be allowed. The Set method, which does the same thing as a constructor, should also be supported, except that it allows the radius of an already created object to be changed later.
The Cylinder class constructor requires two parameters that represent the base radius and the height of the roller, respectively. Instances of this class also cannot be created without specifying the mentioned information. It should also support the "Set" function, which does the same thing as a constructor, except that it allows you to modify an already created object.
Both classes must have other methods (listed in code).
I need to use class Circle inside class Cylinder to enable calculating volume, area, and other functions.
#include <cmath>
#include <iostream>
class Circle {
double radius;
public:
Circle(double r);
void Set(double r);
double GetRadius() const;
double GetPerimeter() const;
double GetArea() const;
void Scale(double s);
void Print() const;
};
class Cylinder {
Circle baze;
double height;
public:
Cylinder(double r_baze, double h);
void Set(double r_baze, double h);
Circle GetBaze() const;
double GetRadiusOfBaze() const;
double GetHeight() const;
double GetArea() const;
double GetVolume() const;
void Scale(double s);
void Print() const;
};
int main() {
return 0;
}
Circle::Circle(double r) {
radius = r;
}
void Circle::Set(double r) {
radius = r;
}
double Circle::GetRadius() const { return radius; }
double Circle::GetPerimeter() const { return 2 * 4 * atan(1) * radius; }
double Circle::GetArea() const { return radius * radius * 4 * atan(1); }
void Circle::Scale(double s) {
radius *= s;
}
void Circle::Print() const {
std::cout << "R= " << GetRadius() << " O= " << GetPerimeter()
<< " P= " << GetRadius();
}
Cylinder::Cylinder(double r_baze, double h) {
baze.GetRadius() = r_baze;
height = h;
}
void Cylinder::Set(double r_baze, double h) {
baze.GetRadius() = r_baze;
height = h;
}
Circle Cylinder::GetBaze() const { return baze; }
double Cylinder::GetRadiusOfBaze() const { return baze.GetRadius(); }
double Cylinder::GetHeight() const { return height; }
double Cylinder::GetArea() const {
return baze.GetArea() * 2 + baze.GetPerimeter() * height;
}
double Cylinder::GetVolume() const { return baze.GetArea() * height; }
void Cylinder::Scale(double s) {
baze.GetRadius() *= s;
height *= s;
}
void Cylinder::Print() const {
std::cout << "R= " << baze.GetRadiusOfBaze() << " H= " << height
<< " P= " << GetArea() << " V= " << GetVolume();
}
I'm new to objected-oriented programming concept. Could you help me to understand where I'm making mistakes?
I cannot compile this, because I get errors:
57 : no matching function for call to ‘Circle::Circle()’
14: note: candidate: ‘Circle::Circle(double)’
14: note: candidate expects 1 argument, 0 provided
3: note: candidate: ‘constexpr Circle::Circle(const Circle&)’
3: note: candidate expects 1 argument, 0 provided
62, 70, 91 : lvalue required as left operand of assignment
Cylinder::Cylinder(double r_baze, double h) {
baze.GetRadius() = r_baze;
height = h;
}
In your Cylinder class, when your constructor is called, baze is implicitly initialized with a default constructor that does not exist.
You want to use an initializer list to handle that initialization, at which point the code inside your Cylinder constructor becomes unnecessary.
Cylinder::Cylinder(double r_baze, double h)
: baze(r_baze), height(h) {
}
Alternatively, you could provide functionally a default constructor for your Circle class, and then Set the radius in Cylinder's constructor, but that's more work.
Circle::Circle(double r=0.0) {
radius = r;
}
Cylinder::Cylinder(double r_baze, double h) {
baze.Set(r_baze);
height = h;
}
Also...
Please note that GetRadius returns a double and cannot be assigned to, so you will get an error on that line of code.

C++: undefined reference to Constructor

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

How do I call a function from a given class in a different class

I want to declare a function in one class and run it in a different one.Below is the implementation of my class
#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int myNo = 1 + rand () % 10;
class Point {
protected: int x; int y;
Point() {
x = myNo;
y = myNo;
}
float distanceBetweenMeAndAnotherPoint (Point anotherPoint){
float xyz = sqrt(pow((x-x),2) + pow((y-y),2));
return xyz;
}
};
class Circle : public Point {
private:
int radius;
Circle(int x, int y){
radius=myNo;
}
public:
printCircleInfo(){
cout << x << " " << y << " " << radius << " ";
return 1;
}Point Obj;
bool doIBumpIntoAnotherCircle (Circle anotherCircle){
if (radius + radius >=Obj.distanceBetweenMeAndAnotherPoint)
return true;
else
return false;
}
};
What should I replace Obj.distanceBetweenMeAndAnotherPoint with in order to call the function in this class?
Please provide an example in your answer. Thank you for your time.
You should use the parameter that you get, like this:
float distanceBetweenMeAndAnotherPoint (Point anotherPoint){
float dist = sqrt(pow((x-anotherPoint.x),2) + pow((y-anotherPoint.y),2));
return dist;
}
Also for the bump method, use the parameter that you get. And additionally simplify boolean return value, no need for the if-else. Resulting with something like:
bool doIBumpIntoAnotherCircle (Circle anotherCircle) {
return distanceBetweenMeAndAnotherPoint(anotherCircle)
<= (radius + anotherCircle.radius);
}
Note also that constructors should usually (though not necessarily) be public. In your case, the ctor of both classes, Point and Circle, should most likely be public and not private or protected to allow creation of objects of these types in your main.

How I can use C++ STL Sort for sorting array of object with inheritance

Im trying to sort an array of objects by one of their attributes using c++ STL sort() but I always get an error:
main.cpp: In function 'bool sortByArea(const Shape*, const Shape*)':
main.cpp:54:22: error: passing 'const Shape' as 'this' argument of 'double Shape::getArea()' discards qualifiers [-fpermissive]
return lhs->getArea() < rhs->getArea();
^
main.cpp:54:39: error: passing 'const Shape' as 'this' argument of 'double Shape::getArea()' discards qualifiers [-fpermissive]
return lhs->getArea() < rhs->getArea();
Here is my code:
Shape.cpp
#include "Shape.h"
Shape::Shape(){
width=0;
height=0;
area=0;
perimeter=0;
}
Shape::Shape(double newwidth, double newheight, double newarea, double newperimeter){
width=newwidth;
height=newheight;
area=newarea;
perimeter=newperimeter;
}
Shape::~Shape(){
}
double Shape::getWidth(){
return width;
}
double Shape::getHeight(){
return height;
}
double Shape::getArea(){
return area;
}
double Shape::getPerimeter(){
return perimeter;
}
double Shape::calArea(){
return 0;
}
double Shape::calPerimeter(){
return 0;
}
Circle.cpp
#include "Circle.h"
#include <cmath>
#define PI 3.141592654
Circle::Circle(){
width = height = 0;
area=0; perimeter=0;
}
Circle::Circle(double newradius){
width = height = newradius;
area = calArea(); perimeter = calPerimeter();
}
Circle::~Circle(){
}
double Circle::calArea(){
return (pow(width,2)*PI);
}
double Circle::calPerimeter(){
return (width * PI * 2);
}
main.cpp
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
#include "Square.h"
#include <fstream>
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int size = 200;
int cshape = 0; int rshape = 0; int sshape = 0;
void input_circle(Shape* mshape){
ifstream file;
int i;
double r;
file.open("circle.txt");
while (file >> r){
Circle crl(r);
mshape[cshape]=crl;
cshape++;
}
file.close();
}
bool sortByArea(const Shape * lhs, const Shape * rhs) {
return lhs->getArea() < rhs->getArea();
}
int main(){
Shape* shapecir;
shapecir = new (nothrow) Circle[size]();
input_circle(shapecir);
int i;
cout << "Circle" << endl;
sort(shapecir,shapecir+size,sortByArea);
for (i=0;i<cshape;i++)
cout << shapecir[i].getArea() << " " << shapecir[i].getPerimeter() << endl;
return 0;
}
I tried to find something on the internet but I can't find anything that can help.
You ought to have tested these functions as you wrote them. The problem is here:
double Shape::getArea(){
return area;
}
bool sortByArea(const Shape * lhs, const Shape * rhs) {
return lhs->getArea() < rhs->getArea();
}
You correctly gave sortByArea const pointer arguments, but neglected to make getArea a const function. The compiler is telling you that you are commanding that the code perform an operation that might change the shapes, after you forbade that they be changed.

Have shape and circle class, and point class. Segmentation fault when creating circle with point class as one parameter

Here is my Shape.h. Ignore all the code that is commented out. That is from a version that I believe was incorrect but I left it in there in case I was wrong.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <math.h>
#include "Point.h"
using namespace std;
class Shape {
public:
Shape() {}
virtual ~Shape() {}
/*
virtual float calcArea(const Shape& s) const = 0;
virtual float calcCircum(const Shape& s) const = 0;
virtual string calcBox(const Shape& s) const = 0;
virtual void display(const Shape& s) const = 0;
*/
virtual float calcArea() const = 0;
virtual float calcCircum() const = 0;
virtual string calcBox() const = 0;
virtual void display() const = 0;
};
class Circle : public Shape {
public:
int radius;
int pointX;
int pointY;
Point *middlePoint;
float PI;
Circle() : Shape() {
middlePoint = new Point(0,0);
radius = 0;
}
~Circle() {}
Circle(int rad, Point& p) : Shape() {
PI = 3.141592;
*middlePoint = p;
pointX = p.getX();
pointY = p.getY();
radius = rad;
}
// float calcArea(const Circle& s) const {
float calcArea() const {
float tempArea;
// tempArea = PI * s.radius * s.radius;
tempArea = PI * radius * radius;
return tempArea;
}
// float calcCircum(const Circle& s) const {
float calcCircum() const {
// int diameter = 2 * s.radius;
int diameter = 2 * radius;
float tempCircum;
tempCircum = PI * diameter;
return tempCircum;
}
// string calcBox(const Circle& s) const {
string calcBox() const {
// int x = s.pointX;
// int y = s.pointY;
// int r = s.radius;
int x = pointX;
int y = pointY;
int r = radius;
int tlX = x - r;
int tlY = y + r;
int blX = x - r;
int blY = y - r;
int trX = x + r;
int trY = y + r;
int brX = x + r;
int brY = y - r;
Point *topLeft = new Point(tlX,tlY);
Point *bottomLeft = new Point(blX,blY);
Point *topRight = new Point(trX,trY);
Point *bottomRight = new Point(brX,brY);
stringstream output;
string tempOut;
output << *topLeft << *bottomLeft << *topRight << *bottomRight;
tempOut = output.str();
return tempOut;
}
// void display(const Circle& s) const {
void display() const {
cout << "Class Name: Circle" << endl;
// float tmpArea = calcArea(s);
float tmpArea = calcArea();
cout << "Area = " << tmpArea << endl;
// cout << "Radius = " << s.radius << endl;
cout << "Radius = " << radius << endl;
// float tmpCircum = calcCircum(s);
float tmpCircum = calcCircum();
cout << "Circumference = " << tmpCircum << endl;
cout <<"Middle Point = " << middlePoint;
// string bbox = calcBox(s);
string bbox = calcBox();
cout <<"Bounding Box Points = " << bbox;
}
};
Here is my TMA4Question1.cpp code.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <math.h>
#include "Shape.h"
int main() {
Point *circlePoint = new Point(10,-5);
Circle *mainCircle = new Circle(23,*circlePoint);
}
Ok. Yes this is a homework assignment for University. I'm not looking just for the answer, I would like to know why this program gives me a segmentation fault and how to correct it.
I know the error is in the Circle code, where I pass a pointer to the circlePOint in the constructor for the Circle class. I dont know why it generates a seg fault. I hope someone can provide some insight. Thanks.
Sorry if the code is messy. Had a hard time pasting it into here properly with 4 spaces and all that.
middlePoint is not allocated in your second Circle constructor. You are assigning a value to it before giving it some memory. As an aside, I don't see why anything there needs to be a pointer.
Why do you use pointers to Points inside your classes at all? You only generate memory leaks this way and (without your own copy operations) cause problems with as the midpoints could be shared by different circles.
PS: And it's not needed to have a PI value (even as non-const) in every circle - just use the constant from (afair) cmath for it.