I have declared two constant functions in a header file that pop an error when I try to define them in an implementation file.
I noticed that removing "const" from the declaration gets rid of the errors but it is required by the professor that the methods are constant in the header file.
//header file
#ifndef DEGREE_RVC_H
#define DEGREE_RVC_H
#include <iostream>
using namespace std;
class degree {
public:
degree();
degree(double);
degree(double, char);
void setAll(double, char);
void setTemp(double);
void setScale(char);
double getF() const;
double getC() const;
private:
double temp;
char scale;
};
#endif
//implementation file
double degree::getC()
{
if (scale == 'c') {
return temp;
}
else return 5.0 / 9.0 * (temp - 32);
}
double degree ::getF()
{
if (scale == 'f') {
return temp;
}
else return temp * (9.0 / 5.0) + 32;
}
The getF and getC methods give me the same errors that refer me to the line they were declared in the header file, but the specific error is "declaration is incompatible with double degree::'methodname()' const"
Declarations and definitions need to match. Since you can't (and shouldn't) remove const from the declarations, add it to the definitions.
double degree::getC() const
{
...
}
double degree ::getF() const
{
...
}
Related
I'm making a heap class to be importable with heap.h and my constructors including bool types do not work, yet every other constructor and function imported works.
Here is what's in heap.h:
#ifndef __HEAP_INCLUDED__
#define __HEAP_INCLUDED__
#include <iostream>
#include <vector>
using namespace std;
class heap{
int capacity;
bool isMinHeap; //1 is min heap -- ascending order
vector<int> * content;
public:
heap();
heap(bool t);
heap(vector<int> * input);
heap(vector<int> * input, bool t);
void print();
void prettyPrint();
int parent(int i);
int leftChild(int i);
int rightChild(int i);
int size();
int getMax();
void insert(int data);
void heapifyDown(int index);
void heapifyUp(int index);
int invalidChild(int index);
int deleteMax();
int deleteMin();
bool minDir();
int at(int index);
};
vector<int> * heapSort(vector<int> * input);
void swap(vector<int> * vec, int a, int b);
#endif
Here are the defined constructors in heap.cpp. Note, all constructors work fine when I add a main to this file to test stuff:
class heap{
vector<int> * content;
int capacity = 256;
bool isMinHeap; //1 is min heap -- ascending order
public:
heap(){
content = new vector<int>;
isMinHeap = 0;
}
heap(bool t){
content = new vector<int>;
isMinHeap = t;
}
heap(vector<int> * input){
content = input;
isMinHeap = true;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
heap(vector<int> * input, bool t){
content = input;
isMinHeap = t;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
//other functions below
}
The constructors with bool do not work in main.cpp, which has #include "heap.h" at the top. The files are all in the same directory and I am compiling with this command: g++ heap.cpp main.cpp -o main. Why do two of my constructors not work?
The error I see is
/usr/bin/ld: /tmp/ccwomODk.o: in function `main':
main.cpp:(.text+0x4e2): undefined reference to `heap::heap(bool)'
collect2: error: ld returned 1 exit status
-Wall does not elaborate on the issue. I'm pretty sure the issue is with my linking somewhere because the constructors work inside of heap.cpp when I use them in there.
What you are doing with the class in the .cpp file is wrong. You are not allowed to define the class twice. There must only be one class heap { /*...*/ }; in the program (but it may be included in multiple .cpp files). Otherwise the one-definition-rule (ODR) is violated and the program has undefined behavior.
So remove everything you are showing from heap.cpp.
To define the constructors of heap in the heap.cpp file, you need to use this syntax:
#include "heap.h"
heap::heap() {
/*...*/
}
heap::heap(bool t) {
/*...*/
}
//...
and so on. The other member functions must be defined in a similar way, e.g.:
void heap::print() {
/*...*/
}
Furthermore, if you want to have a default member initializer as in
int capacity = 256;
add it in the declaration in the .h file instead.
I also want to add that having a pointer-to-std::vector as member is almost surely a wrong approach as well, but out-of-scope for the question.
When you declare a program element such as a class, function, or
variable, its name can only be "seen" and used in certain parts of
your program. The context in which a name is visible is called its
scope. For example, if you declare a variable x within a function, x
is only visible within that function body.
It seems you broke ODR rule so bad. Your class members including constructors has no body declared in the source file(heap.cpp).
Use '::' to make class members have a body:
//heap.cpp
"heap.h"
heap::heap()
{
}
heap:heap(vector<int> * input, bool t)
{
}
int heap::parent(int i)
{
return i;
}
// this is how you create a body for function that are class members
// the same should be done for all other functions
Object-oriented C++ here.
I'm supposed to code a Microwave object that "heats" a FrozenMeal object.
One method of the Microwave object, called void heatMeal(FrozenMeal), is supposed to take an instance of a FrozenMeal object as a parameter and increase its temperature.
FrozenMeal.h
#include <string>
class FrozenMeal {
public:
FrozenMeal(std::string, int);
void setTemperature(double);
std::string getName() const;
int getVolume() const;
double getCoeffizient() const;
double getTemperature() const;
private:
std::string name;
int volume;
double temperature;
double coeffizient;
};
FrozenMeal.cpp
#include <string>
#include "FrozenMeal.h"
using namespace std;
FrozenMeal::FrozenMeal(string mealName, int mealVolu) {
name = mealName;
volume = mealVolu;
temperature = -18;
coeffizient = 0.24;
}
void FrozenMeal::setTemperature(double mealTemp) { temperature = mealTemp; }
string FrozenMeal::getName() const { return name; }
int FrozenMeal::getVolume() const { return volume; }
double FrozenMeal::getCoeffizient() const { return coeffizient; }
double FrozenMeal::getTemperature() const { return temperature; }
Microwave.h
#include "FrozenMeal.h"
class Microwave {
public:
Microwave();
void morePower();
void lessPower();
void setPeriod(double);
void heatMeal(FrozenMeal); // <----------------------------
int getPower() const;
double getPeriod() const;
private:
int power;
double period;
};
Microwave.cpp
#include "Microwave.h"
using namespace std;
Microwave::Microwave() {}
void Microwave::morePower() { if (power < 1000) power += 200; }
void Microwave::lessPower() { if (power > 200) power -= 200; }
void Microwave::setPeriod(double sessionPeri) { period = sessionPeri; }
void Microwave::heatMeal(FrozenMeal mealInst) {
mealInst.setTemperature(80); //example
}
int Microwave::getPower() const { return power; }
double Microwave::getPeriod() const { return period; }
Now, my problem is that my compiler says that the file FrozenMeal.h apparently redefines the object type of FrozenMeal, even though that should be the job of the FrozenMeal.cpp file, and compiling is unsuccessful.
I tried including FrozenMeal.h to Microwave.cpp but that resulted in even more compiler errors.
I feel like I'm doing something horribly wrong here.
Add include guards to your header files so its contents doesn't get included more than once:
FrozenMeal.h:
#ifndef FROZENMEAL_H_INCLUDED
#define FROZENMEAL_H_INCLUDED
// your code ...
#endif /* FROZENMEAL_H_INCLUDED */
Microwave.h:
#ifndef MICROWAVE_H_INCLUDED
#define MICROWAVE_H_INCLUDED
// your code ...
#endif /* MICROWAVE_H_INCLUDED */
Also, you never initialize int Microwave::power and double Microwave::period so you will read and write garbage values in Microwave::morePower() and Microwave::lessPower()
As suggested in the comments, you want to take the parameter of Microwave::heatMeal() by reference so the function can modify the passed object:
void Microwave::heatMeal(FrozenMeal &mealInst)
// ^
For a simple game, I have the following classes:
// color.h
#ifndef COLOR_H
#define COLOR_H
#include "ns.h"
BEGIN_NS
enum class color {
white,
black
};
END_NS
#endif
and
// position.h
#ifndef POSITION_H
#define POSITION_H
#include <string>
#include "ns.h"
BEGIN_NS
struct position {
int rank, file; // The rank and file
public:
std::string code() const;
bool valid() const {
return rank >= 0 && rank < ranks && file >= 0 && file < files;
}
bool at(int r, int f) const { return rank == r && file == f; }
bool at(const position &p) const { return rank == p.rank && file == p.file; }
public:
static position from_code(std::string code);
};
END_NS
#endif
and, finally
#ifndef PIECE_H
#define PIECE_H
#include <string>
#include "color.h"
#include "position.h"
BEGIN_NS
class board;
class piece {
protected:
piece(const std::string& type, color c, const position &start_pos);
const color _color; // The color of the piece
const position _start_pos; // The initial starting position of this piece
position _pos; // The current position of the piece
int _times_moved; // The number of times the piece was moved
bool _captured; // Defines whether the piece has been captured
const std::string _type; // Defines the type of piece
public:
const position& start() const { return _start_pos; }
const position& position() const { return _pos; }
color color() const { return _color; }
bool captured() const { return _captured; }
int moved() const { return _times_moved; }
bool enemy_of(const piece* p) const { return p && p->color() != _color; }
bool ally_of(const piece* p) const { return p && p->color() == _color; }
void capture() { _captured = true; }
virtual piece* eval(const board* board, const position &pos) const = 0;
};
END_NS
#endif
Also, the namespace macros are defined in ns.h:
#define BEGIN_NS namespace chess_game {
#define END_NS }
The problem is with the position structure usage in my piece.h file, specifically at the virtual piece* eval(...) function. The compiler cannot resolve position as a valid type, but it does not complain about position being used as a constructor arg, as two of the field types and as a return type to the start() and position() functions. Specifically, the compiler says:
IntelliSense function "chess_game::piece::position" is not a type name
C4430: missing type specifier - int assumed. Note C++ does not support default int
C2143: syntax error: missing ',' before '&'
The position parameter type in the eval function prototype is underlined, but none of the other usages of the type are underlined. If I fully qualify just that instance of position with my namespace using scope resolution, then the error goes away. If I remove just the eval function from the class, the error goes away. Why would it require the type to be fully qualified in the function parameter signature and not anywhere else in the class? Qualifying the parameter type with the namespace isn't a big deal, I just wish to know why I have to and what the problem is...
Visual Studio 2013 C++ compiler
Thanks for the assistance.
class piece {
// ...
const position& position() const { return _pos; }
// ...
The member function chess_game::piece::position() const hides the type chess_game::position() in the scope of piece. After that member function has been declared, you can no longer use just position to refer to the class.
Avoid using the same name for a type and a function.
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())
Can't get this code to compile and work properly
The implementation file:
#include <cmath>
#include "quadEquation.h"
using namespace std;
QuadEquation::QuadEquation()
{
int a,b,c;
}
QuadEquation::QuadEquation(int first, int second, int third)
{
a = first;
b = second;
c = third;
}
int QuadEquation::getA()
{
return a;
}
int QuadEquation::getB()
{
return b;
}
int QuadEquation::getC()
{
return c;
}
int QuadEquation::getDiscriminant()
{
return b * b - 4 * a * c;
}
int QuadEquation::getRoot1()
{
discrim = getDiscrimant();
return -b + sqrt(discrim) / (2 * a);
}
int QuadEquation::getRoot2()
{
discrim = getDiscriminant();
return -b - sqrt(discrim) / (2 * a);
}
The header file:
#ifndef QUADEQUATION_H
#define QUADEQUATION_H
class QuadEquation
{
private:
int a, b, c;
public:
QuadEquation(int, int, int);
int getA();
int getB();
int getC();
int getDiscriminant();
int getRoot1();
int getRoot2();
};
#endif
#include <iostream>
#include "quadEquation.h"
using namespace std;
int main()
{
QuadEquation quad1(1,0,9);
cout << "The first root of the first quadratic equation is: " << quad1.getRoot1() << endl;
return 0;
}
Some errors that i am getting
quadEquation.cpp:5: error: prototype for ‘QuadEquation::QuadEquation()’ does not match any in class `QuadEquation`
quadEquation.h:5: error: candidates are: `QuadEquation::QuadEquation(const QuadEquation&)`
quadEquation.h:10: error: `QuadEquation::QuadEquation(int, int, int)`
quadEquation.cpp: In member function `int QuadEquation::getRoot1()`:
quadEquation.cpp:35: error: `discrim` was not declared in this scope
quadEquation.cpp:35: error: `getDiscrimant` was not declared in this scope
quadEquation.cpp: In member function `int QuadEquation::getRoot2()`:
quadEquation.cpp:40: error: `discrim` was not declared in this scope
One of the constructors you've defined is
QuadEquation::QuadEquation()
{
int a,b,c;
}
But this constructor isn't defined in your header file. Moreover, it looks like this is an error on your part, since this constructor doesn't make much sense - it just declares three local variables and doesn't use any of them. If you do want to declare this constructor, add it to your header file, but judging from your code I don't believe it's necessary.
As to your other errors, look at this code:
int QuadEquation::getRoot1()
{
discrim = getDiscrimant();
return -b + sqrt(discrim) / (2 * a);
}
Two things jump out at me. First, where is discrim declared? Second, if quadratic formulas can have arbitrary complex-valued roots, is there a reason you're returning an int? Is there a different type you could use here instead?
Overall, you should learn to read these compiler error messages. Everything I've pointed out could easily have been gleaned from the error output. Now that you're aware what the problems are, can you see how they generate the given compiler errors?
Hope this helps!