Basic Shape class and Circle Class: compiling error - c++

I have this homework assignment to do and I did most of the code, but I have a remaining compiling error in main(), that I do not understand.
Here's the assignment:
Define an abstract base class called BasicShape. The BasicShape class should have the following members (...)
Define a class named Circle. It should be derived from the BasicShape class.
It should have the following members:
a) Private Member Variable: radius (a double used to hold the circle’s
radius)
b) Constructor and Public Member Functions:
Circle(double a, string
n, double r): constructor that should call the base class constructor
to initialize the member area with a and name with n. The constructor
will also set the value of member radius with r
calcArea():
Overridden function (...)
print(): Overridden function (...)
After you have created these classes, create a test program
(...)
And here's my code:
Basic Shape.h
#ifndef BASICSHAPE_H
#define BASICSHAPE_H
#include <string>
class basicShape
{
public:
basicShape(const std::string &, double &);
double getArea() const;
virtual double calcArea() const = 0;
virtual void print()const;
std::string getname()const;
protected:
const double area;
private:
const std::string name;
};
#endif
Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include <string>
#include "Basic Shape.h"
using namespace std;
class Circle : public basicShape
{
public:
Circle(const string & n, double & a, double & r);
virtual double calcArea() const override;
virtual void print() const override;
private:
double radius;
};
#endif
Circle.cpp
#include <iostream>
#include "Circle.h"
#include<string>
using namespace std;
Circle::Circle(const string &n, double &a, double &r)
:basicShape(n,a)
{
radius = r;
calcArea();
}
double Circle::calcArea() const
{
double area;
area = 3.14159*radius*radius;
return area;
}
double basicShape::getArea() const
{
return area;
}
void Circle::print() const
{
cout << "radius:" << radius;
basicShape::print();
basicShape::getname();
}
Test.cpp
#include <iostream>
#include "Basic Shape.h"
#include "Circle.h"
#include <string>
#include<vector>
using namespace std;
void poly(const basicShape * const);
int main()
{
Circle circle("Round",0.0,10.0);
vector< basicShape * > shapes(1);
for (const basicShape *basicshapePtr : shapes)
poly(basicshapePtr);
}
void poly(const basicShape * const baseClassPtr)
{
baseClassPtr->calcArea();
baseClassPtr->print();
}
Here is the compiling error I get in main:
"Circle::Circle(Circle Assignment 3 &&)': cannot convert argument 2 from 'double' to 'double &'

The problem
You try to construct your new circle here:
Circle circle("Round",0.0,10.0);
But your constructor has the following signature:
Circle(const string &n, double &a, double &r)
For the second and third arguments you use references to double values. Passing by reference like this means that you could change the value that is referenced. Unfortunately, you pass constant literals. This is not allowed.
The solution
Either define your constructor by using const references:
Circle(const string &n, const double &a, const double &r)
or, pass by value:
Circle(string n, double a, double r)
Note that the second option seems preferred here. And I'd even advise you to respect the signature given in the assignment, which would have avoided you those troubles.
P.S.: For future questions, please reduce the question to the minimal elements required to reproduce the errors, instead of posting the full assignment and the full code, most of which being not relevant to the error

Related

How can I create the getter and setter for the vector?

Vector2D hpp files
#ifndef Vector2D_hpp
#define Vector2D_hpp
#include <iostream>
#include "Point2D.hpp"
namespace GeoBox{
class Vector2D{
Point2D m_point1{};
Point2D m_point2{};
public:
Vector2D() = default;
Vector2D(Point2D &point1, Point2D &point2)
{
m_point1 = point1;
m_point2 = point2;
}
void setVector(Point2D &point1, Point2D &point2);
};
Vector2D.cpp files
#include "Vector2D.hpp"
#include "Point2D.hpp"
void GeoBox::Vector2D::setVector(GeoBox::Point2D &point1, GeoBox::Point2D &point2) {
Vector2D(point1, point2);
}
main.cpp
int main(int argc, const char * argv[]) {
GeoBox::Point2D point1{3.0, 1.0};
GeoBox::Point2D point2{2.0, 3.0};
GeoBox::Vector2D vect1{point1, point2};
}
I am trying to create a vector consisting of 2 points. how can i create their getters and settlers? I think I created the setter function, but I'm not sure.
note:GeoBox my file name
To create a vector, you should initialize it as a template type.
For the setter function you must implement the erase () function that can receive two iterators, one that points to the value you want to delete or two iterators if you want to delete an element range pointing to the initial and last value.
 
The erase () function is already a function implemented in c ++ 11 but it can be developed.
Its seems like this might work. I changed your class to store pointers and not objects for efficiency. Granted, I can't test that this because I don't have the rest of your code and can't guarantee your setup.
#ifndef Vector2D_hpp
#define Vector2D_hpp
#include <iostream>
#include "Point2D.hpp"
namespace GeoBox {
class Vector2D {
Point2D* points[2];
public:
Vector2D() = default;
Vector2D(Point2D* point1, Point2D* point2)
{
setVector(point1, point2);
}
void setVector(Point2D* point1, Point2D* point2) {
points[0] = point1;
points[1] = point2;
}
Point2D* getVector() {
return points;
}
};
}
#endif
To do this with a struct (and without pointers in this case) you would set it up like this:
#ifndef Vector2D_hpp
#define Vector2D_hpp
#include <iostream>
#include "Point2D.hpp"
namespace GeoBox {
class Vector2D {
struct Vector { //Define the struct
Point2D point1;
Point2D point2;
} points; //Create instance of struct
public:
Vector2D() = default;
Vector2D(Point2D point1, Point2D point2)
{
setVector(point1, point2);
}
void setVector(Point2D i_point1, Point2D i_point2) {
points.point1 = i_point1; //Access struct components
points.point2 = i_point2;
}
Vector getVector() {
return points; //return struct
}
};
}
#endif
Pointers can (and should) still be used in this case however as they allow for increased speed in your program overall.

Data recirculation between classes in C++ - error: '<class name>' was not declared in this scope

I am preparing a program with several classes, which have to exchange data between each other subsequently in the code. This results in inclusion of classes in each other headers. I have encountered a problem when it came to passing a vector of "Gas" objects to the "Thermal" class method and afterwards trying to pass a changed "Thermal" object to the "Gas" class method. I have tried forward including of the classes in each other header files, but with a miserable result. Maybe I did something wrong with that. Possibly a declaration of a pointers between class objects would solve a problem? I have tired this, but unfortunately I may lack of experience with pointers, as I failed as well.
Notice - When I comment out the #include "Thermal.h" from the "Gas" class, the code compiles successfully. However, then the diffusion method has to be commented out as well.
The compilier returns, as follows:
./src/Thermal.h:86:76: error: template argument 2 is invalid
./src/solution.cpp: In function 'void solution(const Ref::Reformer&,
const std::vector<Ref::Segment>&, std::ofstream*, std::ofstream*, std::ofstream*)':
./src/solution.cpp:92:40: error: no matching function for call to 'Ref::Thermal::
conduction(const Ref::Reformer&, Ref::Grid&, std::vector<Ref::Gas>&, Ref::Velocity&)'
T.conduction(reactor, grid, gases, vel);
^
In file included from ./src/Gas.h:20:0,
from ./src/solution.cpp:16:
./src/Thermal.h:86:8: note: candidate: void Ref::Thermal::conduction(const Ref::Reformer&,
const Ref::Grid&, const int&, const Ref::Velocity&)
void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS,
const Velocity& VE);
^
./src/Thermal.h:86:8: note: no known conversion for argument
3 from 'std::vector<Ref::Gas>' to 'const int&'
Here is how I call the methods. Objects of class "Thermal" and "Gas" are created in the same .cpp file and are called subsequently. Their initialization requires construction and passing of a "Grid" class object, which is done in the same file as well.
Objects creation:
Grid grid(0.3, 0.052);
grid.setNX(90);
grid.setNR(15);
Thermal T(grid);
for(i = 0; i < 6; i++){
gases.push_back(Gas(i, grid));
}
Methods' call:
T.conduction(reactor, grid, gases, vel);
for(int i = 0; i < gases.size(); i++){
gases[i].diffusion(reactor, grid, vel, T);
}
Grid class declaration:
#ifndef REFORMING_CODE_REF_GRID_H
#define REFORMING_CODE_REF_GRID_H
#include "../input.h"
namespace Ref{
class Grid{
public:
Grid(const double& x1, const double& r1, const double& x0 = 0., const double& r0 = 0.){
xmin_ = x0;
xmax_ = x1;
rmin_ = r0;
rmax_ = r1;
}
void setNX(const int& nx){ //setting number of elements in the longitudinal direction
NX_ = nx;
ni_ = NX_ - 1;
}
void setNR(const int& nr){ //setting number of elements in the radial direction
NR_ = nr;
nj_ = NR_ - 1;
}
};
}//end of namespace
#endif //REFORMING_CODE_REF_GRID_H
Thermal class declaration:
#ifndef REFORMING_CODE_REF_THERMAL_H
#define REFORMING_CODE_REF_THERMAL_H
#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Gas.h"
namespace Ref{
class Thermal{
public:
Thermal(const Grid& grid){
NX_ = grid.NX();
NR_ = grid.NR();
}
void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS, const Velocity& VE);
private:
int NX_; //quantity of elements in the X direction
int NR_; //quantity of elements in the R direction
std::vector<double> val_; //Temperature value (K)
std::vector<double> val_old_;
std::vector<double> s_; //Thermal source
};
} //end of namespace
#endif //REFORMING_CODE_REF_THERMAL_H
Conduction method definition:
#include "Thermal.h"
namespace Ref{
void Thermal::conduction(const Reformer& RE, const Grid& GD,
const std::vector<Gas>& GAS, const Velocity& VE){}
}
Gas class declaration:
#ifndef REFORMING_CODE_REF_GAS_H
#define REFORMING_CODE_REF_GAS_H
#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Thermal.h"
namespace Ref{
class Gas{
public:
Gas(const int id, const Grid& grid){
id_ = id;
NX_ = grid.NX();
NR_ = grid.NR();
}
void diffusion(const Reformer&, const Grid&, const Velocity&, const Thermal&);
private:
int id_;
int NX_;
int NR_;
};
} //end of namespace
#endif //REFORMING_CODE_REF_GAS_H
Diffusion method definition:
#include "Gas.h"
namespace Ref{
void Gas::diffusion(const Reformer& RE, const Grid& GD,
const Velocity& VE, const Thermal& T){}
} //end of namespace
You could try using forward declarations and moving the #include to the end of the header. ( your file wouldn't be included twice because of the header guards )
Minimal compiling example:
//RecursiveA.h
#ifndef RECURSIVEA_H
#define RECURSIVEA_H
class RecursiveA {
public:
void workOnB(const class RecursiveB &);
};
#include "RecursiveB.h"
#endif // RECURSIVEA_H
//RecursiveB.h
#ifndef RECURSIVEB_H
#define RECURSIVEB_H
class RecursiveB {
public:
void workOnA(const class RecursiveA &);
};
#include "RecursiveA.h"
#endif // RECURSIVEB_H
//RecursiveA.cpp
#include "RecursiveA.h"
void RecursiveA::workOnB(const RecursiveB &b){
}
//RecursiveB.cpp
#include "RecursiveB.h"
void RecursiveB::workOnA(const RecursiveA &a){
}

C++ error when invoking a constructor that does not exist

I'm playing with a simple little inheritance program and I accidentally tried to invoke a constructor that didn't exist and I'm trying to understand the error.
Shape.h
#pragma once
#include "stdafx.h"
#include "string"
#include "iostream"
using namespace std;
enum triangle_type
{
Isoceles,
Scalene,
Equilateral,
Right,
ThreeFourFive
};
class Shape
{
public:
//constructor/destructor
Shape();
Shape(string name);
void Test()
{
enum Color { Red, Blue, Green };
Color color;
int thisThing = Red;
}
Shape* Create(Shape* shape);
virtual string Name();
virtual double Area() = 0;
~Shape();
private:
string name;
triangle_type triangleType;
};
Triangle.h
#pragma once
#include "Shape.h"
#include "string"
class Triangle :
public Shape
{
public:
Triangle();
Triangle(string);
Triangle(int, int);
//Triangle(int); missing constructor
~Triangle();
double Area();
string Name();
private:
int height, base;
string name;
};
Triangle.cpp
#include "stdafx.h"
#include "Triangle.h"
#include "string"
using namespace std;
Triangle::Triangle()
{
}
Triangle::Triangle(string name):
Shape(name)
{
this->name = name;
}
Triangle::Triangle(int newBase, int newHeight)
{
base = newBase;
height = newHeight;
}
Triangle::Triangle(int newBase)
{
base = newBase;
//C2597-you can get an illegal reference to non-static member
//if you try to use a constructor that you don't have defined in your header file
}
double Triangle::Area()
{
return 0.5*(base * height);
}
string Triangle::Name()
{
return "Triangle!";
}
Triangle::~Triangle()
{
}
main.cppp
#include "stdafx.h"
#include "Shape.h"
#include "Triangle.h"
int _tmain(int argc, _TCHAR* argv[])
{
Shape *shape = new Triangle("My triangle");
double area = shape->Area();
Triangle *triangle = new Triangle(3); //error C2664 'Triangle::Triangle(const Triangle&)
//cannot convert argument 1 from 'int' to 'std::string'
shape->Test();
return 0;
}
I recognize that calling the constructor that doesn't exist is why there's an error when I'm calling it, but I have no idea what the error message means. It didn't ring any bells after reading it.
Pretty straightforward error:
cannot convert argument 1 from 'int' to 'std::string'
You have one constructor that takes one argument:
Triangle(string);
So that is the complete overload set that is considered. You are calling it with an int:
Triangle *triangle = new Triangle(3);
There is no other constructor to consider, so the compiler will try all implicit conversions at its disposal - all of which fail. Hence, the compile error.
The compiler will, where possible, convert between types to make a function call succeed. In your case, you have a constructor that takes one argument (a std::string) and so the compiler tries to convert the int you gave to a std::string which it expects. It can't, which is why you get that particular error.

Object is wrong type

Basically for some reason new object is wrong type. All source code is on github https://github.com/teuro/sfml-radar. If it's help please fork at will.
I have following class:
#ifndef _VIEW_HPP
#define _VIEW_HPP
#include <iostream>
#include "sfml_drawsurface.hpp"
class View {
protected:
View(Drawsurface& d) : drawer(d) {
std::clog << "View::View()" << std::endl;
}
Drawsurface& drawer;
virtual void draw() = 0;
};
#endif
That is base class for all different kind of views. Now I have derived sub-class
#ifndef _GAME_VIEW_HPP
#define _GAME_VIEW_HPP
#include <vector>
#include <iostream>
#include <typeinfo>
#include "view.hpp"
#include "../models/game.hpp"
class Gameview : public View {
public:
Gameview(Drawsurface& d);
~Gameview();
void draw();
private:
Drawsurface& drawer;
};
#endif // _GAME_VIEW_HPP
Then abstract class Drawsurface
/**
* drawsurface base for all graphics pure abstract
* provide only interface quite high-level
* 2014/06/02
* Juha Teurokoski
**/
#ifndef _DRAWSURFACE_HPP
#define _DRAWSURFACE_HPP
#include <string>
#include "../models/point.hpp"
class Drawsurface {
public:
bool font_loaded;
virtual void rectangleColor(Point& a, Point& b, unsigned int color) = 0;
virtual void lineColor(Point& a, Point& b, unsigned int color) = 0;
virtual void circleColor(Point& a, unsigned int rad, unsigned int color) = 0;
virtual void trigonColor(Point& a, Point& b, Point& c, unsigned int color) = 0;
virtual void trigonColor(Point& a, unsigned int size, unsigned int color) = 0;
virtual void load_font(std::string font) = 0;
virtual void draw_picture(std::string tiedosto, Point& a, bool center = false) = 0;
virtual void draw_text(std::string text, Point& a, unsigned int color = 0) = 0;
virtual int get_fontsize() = 0;
virtual void flip() = 0;
virtual void clear_screen() = 0;
virtual ~Drawsurface() { }
};
#endif
Now if I create new instance of sfml_drawsurface which is sub-class of Drawsurface. For some reason new object is Drawsuface istead of sfml_drawsurface. Below is sfml_drawsurface class.
#ifndef SFML_DRAWSURFACE_HPP
#define SFML_DRAWSURFACE_HPP
/**
* sfml-drawsurface provides basic drawing, pictures and text
* require drawsurface
* 2014/06/02
* Juha Teurokoski
**/
#include "drawsurface.hpp"
#include <vector>
#include <stdexcept>
#include <iostream>
#include <SFML/Graphics.hpp>
class sfml_drawsurface : public Drawsurface {
public:
sfml_drawsurface(sf::RenderWindow& window);
~sfml_drawsurface();
void rectangleColor(Point& a, Point& b, unsigned int color);
void circleColor(Point& a, unsigned int rad, unsigned int color);
void lineColor(Point& a, Point& b, unsigned int color);
void trigonColor(Point& a, Point& b, Point& c, unsigned int color);
void trigonColor(Point& a, unsigned int _size, unsigned int color);
void draw_picture(std::string tiedosto, Point& a, bool center = false);
void draw_text(std::string text, Point& a, unsigned int color);
void load_font(std::string font);
void clear_screen();
int get_fontsize();
void flip();
protected:
private:
sf::RenderWindow& window;
sf::Font font;
sf::Color active;
sf::Color normal;
};
#endif // SFML_DRAWSURFACE_HPP
I create new object like this:
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
std::clog << typeid(drawer).name() << std::endl;
And everything seems to be right, because std::clog outout is '16sfml_drawsurface'.
Next place is draw-method then happens something really weird.
Same print is now '11Drawsurface'.
Looks like Mike had the right idea. From your Program.cpp file you have in your constructor:
Program::Program() {
Game game;
...
this->gamecontroller = new Gamecontroller(game); //Probably also bad
sfml_drawsurface drawer(window);
this->gameview = new Gameview(drawer);
}
The problem is that drawer ceases to exist once the constructor is finished leaving you with a dangling reference and undefined behaviour. Looks like you may have the same problem with the game variable.
Solution is to not have them as local variables but as either class members (preferred) or dynamically allocated (it depends how long you need to have them around).

Object declaration Error in eclipse

I have edited previous post to give more complete question so:
I have a class named Heliostat that in the header file i want to make 5 objects.3 of them are from class vector and 2 of them from class targets.The vector class constructors needs as operators Target objects or vector objects. I get error that the program does not recognise the operators as any type. I will give you the code.
I work for an arduino project inside eclipse.
This is the heliostat class header:
#ifndef HELIOSTAT_H_
#define HELIOSTAT_H_
#include "Target.h"
#include "TargetCatalog.h"
#include "vector.h"
#include "Sun.h"
class Heliostat {
private:
public:
double Pitch;
double Azimuth;
Target heliostat(4501472.0,662766.0,1.0);
Target reactor(4501474.0,662768.0,30.0);
Vector sunsVec(Sun::getPitch1year(),Sun::getAzimuth1yearArcsin());
Vector reactVec(heliostat,reactor);
Vector normalVec(reactVec,sunsVec);
Heliostat();
virtual ~Heliostat();
};
#endif /* HELIOSTAT_H_ */
It will have some functions that are not writen know.
The cpp has almost nothing only the constructor that is empty.
The Target class header:
#ifndef TARGET_H_
#define TARGET_H_
class Target {
private:
public:
enum targetlist{Helio,React,Normalpoint};
double gpsX;
double gpsY;
double gpsZ;
Target(double gpsEast, double gpsNorth, double gpsAlt);
virtual ~Target();
};
#endif /* TARGET_H_ */
The vectors class header:
#ifndef VECTOR_H_
#define VECTOR_H_
#include "Target.h"
class Vector {
public:
double easting;
double northing;
double altitude;
Vector(Target startTarget,Target endTarget);
Vector(double targetsPitch,double targetsAzimuth);
Vector(Vector reactorVector,Vector sunVector);
double calculateInclinationAngle(Vector reactorVector,Vector sunVector);
double getPitch(Vector helioNormalVec);
double getAzimuth(Vector helioNormalVec);
virtual ~Vector();
};
#endif /* VECTOR_H_ */
and the vector.cpp:
#include "vector.h"
#include "Maths.h"
#include "Target.h"
//vector::vector() {
// // TODO Auto-generated constructor stub
//
//}
vector::vector(Target startTarget, Target endTarget) {
double eastingTemp=endTarget.gpsX-startTarget.gpsX;
double northingTemp=endTarget.gpsY-startTarget.gpsY;
double altitudeTemp=endTarget.gpsZ-startTarget.gpsZ;
double vecMagnitude=sqrt(pow(eastingTemp,2)+pow(northingTemp,2)+pow(altitudeTemp,2));
easting=eastingTemp/vecMagnitude;
northing=northingTemp/vecMagnitude;
altitude=altitudeTemp/vecMagnitude;
}
vector::vector(double targetsPitch, double targetsAzimuth) {
easting=Maths::cosDeg(targetsPitch)*Maths::sinDeg(targetsAzimuth);
northing=Maths::cosDeg(targetsPitch)*Maths::cosDeg(targetsAzimuth);
altitude=Maths::sinDeg(targetsPitch);
}
vector::vector(vector normReactorVec, vector normSunVec) {
double inclinationAngle=calculateInclinationAngle(normReactorVec,normSunVec);
double normalMagnitude=2*Maths::cosDeg(inclinationAngle);
easting=(normReactorVec.easting+normSunVec.easting)/normalMagnitude;
northing=(normReactorVec.northing+normSunVec.northing)/normalMagnitude;
altitude=(normReactorVec.altitude+normSunVec.altitude)/normalMagnitude;
}
double vector::calculateInclinationAngle(vector reactorVector,vector sunVector) {
double angleResult=(reactorVector.easting*sunVector.easting)
+ (reactorVector.northing*sunVector.northing)
+ (reactorVector.altitude*reactorVector.altitude);
double inclinationAngleDoubled=Maths::arccos(angleResult);
double inclinationAngle=inclinationAngleDoubled/2.0;
return inclinationAngle;
}
double vector::getPitch(vector helioNormalVec) {
double pitch=Maths::arcsin(helioNormalVec.altitude);
if (pitch<0){
pitch=0;
Serial.println(F("error on pitch calc"));
}
return pitch;
}
double vector::getAzimuth(vector helioNormalVec) {
double pitch=getPitch(helioNormalVec);
double theta=Maths::arcsin(helioNormalVec.easting/Maths::cosDeg(pitch));
//taking absolute of theta function abs() get only int as operators
if (theta<0){
theta=-theta;
}
double azimuth;
if (helioNormalVec.easting>0){
if(helioNormalVec.northing>0){
azimuth=theta;
}else if(helioNormalVec.northing<0){
azimuth=180-theta;
}else{
azimuth=90;
}
}else if(helioNormalVec.easting<0){
if(helioNormalVec.northing>0){
azimuth=360-theta;
}else if(helioNormalVec.northing<0){
azimuth=180+theta;
}else{
azimuth=270;
}
}else{
if(helioNormalVec.northing>0){
azimuth=0;
}else if(helioNormalVec.northing<0){
azimuth=180;
}else{
Serial.println(F("error on Azimuth calc"));
}
}
return azimuth;
}
vector::~vector() {
// TODO Auto-generated destructor stub
}
About sun class i just use 2 functions that return doubles.
At this poing there is no sketch i do not expect the program to do something i am verifing it for syntax error.
The error i get says that:
'Sun::getPitch1year' is not a type
The same goes for: getAzimuth1yearArcsin(),TargetCatalog::rectorTarget,TargetCatalog::heliostatTarget,reactVec,sunsVec.
For the first lines at the heliostat header.
Target heliostat(4501472.0,662766.0,1.0);
Target reactor(4501474.0,662768.0,30.0);
i get syntax error that says:expected ',' or '...' before numeric constant
is there any solution about these problems?
In heiliostat.h, the line
Vector sunsVec(Sun::getPitch1year(),Sun::getAzimuth1yearArcsin());
declares a function named sunsVec and should declare what types it takes. The current code tries to call two functions.
Replace Sun::getPitch1year() with the type that function returns, and do the same for Sun::getAzimuth1yearArcsin())