Well, I'm writing this code for my class and I'm getting linker errors LNK2019 and LNK1120 using Visual Studio. I'm not all too sure why it's doing what it's doing, but I digress.
Header file:
#ifndef PointClass
#define PointClass
#include <iostream>
namespace PointClass
{
class point
{
public:
// CONSTRUCTOR
point(double initial_x = 0.0, double initial_y = 0.0);
// MODIFICATION MEMBER FUNCTIONS
void shift(double x_amount, double y_amount);
void rotate90( );
// CONSTANT MEMBER FUNCTIONS
double get_x( ) const { return x; }
double get_y( ) const { return y; }
// FRIEND FUNCTION
friend std::istream& operator >>(std::istream& ins, point& target);
double x, y; // x and y coordinates of this point
};
// NONMEMBER FUNCTIONS for the point class
double distance(const point& p1, const point& p2);
point middle(const point& p1, const point& p2);
point operator +(const point& p1, const point& p2);
bool operator ==(const point& p1, const point& p2);
bool operator !=(const point& p1, const point& p2);
std::ostream& operator <<(std::ostream & outs, const point& source);
}
#endif
And the CPP file:
#include <iostream>
#include <math.h>
#include "point.h"
using namespace std;
namespace PointClass
{
point::point(double initial_x, double initial_y)
{
x = initial_x; // Constructor sets point to a given position
y = initial_y;
}
void point::shift(double x_amount, double y_amount)
{
x += x_amount;
y += y_amount;
}
void point::rotate90( )
{
double new_x;
double new_y;
new_x = y; // For a 90 degree clockwise rotation the new y is -1
new_y = -x; // times original x, and the new x is the original y
x = new_x;
y = new_y;
}
bool operator ==(const point& p1, const point& p2)
{
return
(p1.get_x( ) == p2.get_x( ))
&&
(p1.get_y( ) == p2.get_y( ));
}
bool operator !=(const point& p1, const point& p2)
{
return !(p1 == p2);
}
point operator +(const point& p1, const point& p2)
{
double x_sum, y_sum;
// Compute the x and y of the sum:
x_sum = (p1.get_x( ) + p2.get_x( ));
y_sum = (p1.get_y( ) + p2.get_y( ));
point sum(x_sum, y_sum);
return sum;
}
ostream& operator <<(ostream& outs, const point& source)
{
outs << source.get_x( ) << " " << source.get_y( );
return outs;
}
istream& operator >>(istream& ins, point& target)
{
ins >> target.x >> target.y;
return ins;
}
int rotations_needed(point p)
{
int answer;
answer = 0;
while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
{
p.rotate90( );
++answer;
}
return answer;
}
void rotate_to_upper_right(point& p)
{
while ((p.get_x( ) < 0) || (p.get_y( ) < 0))
p.rotate90( );
}
double distance(const point& p1, const point& p2)
{
double a, b, c_squared;
// Calculate differences in x and y coordinates
a = p1.get_x( ) - p2.get_x( ); // Difference in x coordinates
b = p1.get_y( ) - p2.get_y( ); // Difference in y coordinates
// Pythagorean Theorem to calculate square of distance between points
c_squared = a*a + b*b;
return sqrt(c_squared); // sqrt calculates square root
}
point middle(const point& p1, const point& p2)
{
double x_midpoint, y_midpoint;
// Compute the x and y midpoints
x_midpoint = (p1.get_x( ) + p2.get_x( )) / 2;
y_midpoint = (p1.get_y( ) + p2.get_y( )) / 2;
// Construct a new point and return it
point midpoint(x_midpoint, y_midpoint);
return midpoint;
}
}
Is there anything I can do to fix it?
You seem to have a namespace called PointClass, and headers guards using PointClass. Consider changing that for a start.
#ifndef PointClass // Rename this, it might be clashing with your namespace.
#define PointClass
namespace PointClass
Read the error message:
Linker Error 2019: unresolved external symbol 'symbol' referenced in function 'function'
It gives you the name of a global variable or (more likely) a function that is called without definition, i.e. you didn't write a function body for it or did not add the source with its definition to your project.
The error LNK1120 is a consequence of the first error.
Without the complete error message it's hard to tell. As #Darcy pointed out, you should change the names in #ifdefand #define since
#define PointClass
tells the preprocessor to substitute this name with nothing in the following source code. This results in a unnamed local namespace. All names defined inside this local namespace are accessible from inside that compilation unit (cpp file) only.
Choose a unique name for the "include guard" which should not occure anywhere else in the program. A possible pattern could imitate the name of the header file:
#define POINT_H
Related
In my class we are creating a dynamic array and learning how to use free store and de-allocating data correctly. We are creating a Line container that holds a Point class which contains points on a graph, this assignment is building off of another assignment of ours but uses new Line member functions.
I am currently having issues with actually creating the array and populating it with coordinates of points. I am not really sure how to begin writing the Main(), what my idea is so far is to create the Line array that will contain members of my Point class. I want to initialize 5 elements and then add 6 so it will create a new array with more elements.
So far I have the following thought on how to start it.
Line* points = new Line[5];
for ( int i = 0; i < 5; i++ ){
points[i] = 0; //This causes "no match for ‘operator=’ (operand types are ‘Line’ and ‘int’)"
}
Then I would probably try to assign points with members of my point class
Point pointOne(1.0, 1.0)
I've tried adding elements like the following but its incorrect.
points[0] -> (1.0, 1.0);
points[0] = pointOne;
Here are my .h and .cpp files
Line.cpp
#include "Point.h"
#include "Line.h"
#include <stdexcept>
//default constructor
Line::Line(){
size();
index = 0;
points = new Point[size()];
Point::Point();
}
//destructor
Line::~Line(){
delete[] points;
}
void Line::push_back(const Point& p){
if(index == size()) // If array is too small copy all data to a new array, reassign pointer
{
Point * temp = new Point[size() + 5]; //temp array in free store
for(size_t i = 0; i < size(); i++)
{
temp[i] = points[i];
}
delete[] points; //clear array
points = temp; //reassign values
points[index++] = p; //Places p into array
delete[] temp;
points[size()] = (5 + size());
}
else
{
points[index++] = p;
}
}
/**
* Clear the list of points by setting index to 0.
*/
void Line::clear(){
delete[] points;
}
/**
* Return the length of the line. The length is calculated as
* the sum of the distance between all points in the line.
*/
double Line::length(){
double total = 0.0;
for (unsigned int index = 0; (index+1) < 10; index++){ //Loop for index and index+1 to prevent going out of the vector
total += points[index].distance(points[index+1]); //Add up distance (A to B) + (B to C) etc
}
return total;
}
/**
* return the number of Points contained in our line
*/
unsigned int Line::size() const{
int i = 5;
return i;
}
/**
* [] operator override
*/
Point & Line::operator[](int index){ //rewrite out-of-bounds
if(index == size())
{
throw std::out_of_range("Out of bounds.");
}
return points[index];
}
Line.h
#ifndef LINE_H_
#define LINE_H_
#include "Point.h"
class Line {
public:
/**
* Constructor and destructor
*/
Line();
virtual ~Line();
/**
* Add a point to the end of our line. If the line contains
*/
void push_back(const Point& p);
/**
* Clear the list of points
*/
void clear();
/**
* Return the length of the line. The length is calculated as
* the sum of the distance between all points in the line.
*/
double length();
/**
* return the number of Points in our line
*/
unsigned int size() const;
/**
* [] operator override
*/
Point & operator[](int index);
private:
unsigned int index; //index of array
Point *points; //Pointer to data
};
#endif /* LINE_H_ */
Point.cpp
#include "Point.h"
#include "Line.h"
#include <cmath>
#include <stdexcept>
/** default constructor **/
Point::Point(){
// TODO Auto-generated constructor stub
this->x = 0.0;
this->y = 0.0;
}
//Overloaded Constructor
Point::Point(const double x, const double y){
// TODO Auto-generated constructor stub
this->x = x;
this->y = y;
}
/**
* Copy constructor */
Point::Point(const Point & t){
x = t.x;
y = t.y;
}
//Default destructor
Point::~Point() {
// TODO Auto-generated destructor stub
}
//Retrieve X value
double Point::getX() const {
return x;
}
//Retrieve Y value
double Point::getY() const {
return y;
}
//Function for finding distance between 2 points on a graph. Using ((x-p.x)^2+(y-p.y)^2)^1/2
double Point::distance(const Point &p) const{
return sqrt( pow((x - p.getX()),2) + pow((y - p.getY()),2));
}
/**
* Output the Point as (x, y) to an output stream
*/
std::ostream& operator <<(std::ostream &out , const Point &point){
out <<'(' << point.x << ',' << ' ' << point.y << ')';
return out;
}
/**
* Declare math operators
*/
//Addition
Point operator +(const Point &lhs, const Point &rhs){
return Point(lhs.x + rhs.x, lhs.y + rhs.y);
}
//Subtraction
Point operator -(const Point &lhs, const Point &rhs){
return Point(lhs.x - rhs.x, lhs.y - rhs.y);
}
/**
* Copy assignment
*/
Point & Point::operator =(const Point& rhs){
x= rhs.x;
y= rhs.y;
return *this;
}
Point.h
#ifndef POINT_H_
#define POINT_H_
#include <iostream>
class Point {
public:
/**
* Constructor and destructor
*/
Point();
Point(const double x, const double y);
virtual ~Point();
/**
* Get the x value
*/
double getX() const;
/**
* Get the y value
*/
double getY() const;
/**
* Return the distance between Points
*/
double distance(const Point &p) const;
/**
* Output the Point as (x, y) to an output stream
*/
friend std::ostream& operator <<(std::ostream &out, const Point &point);
/**
* Declare comparison relationships
*/
friend bool operator ==(const Point &lhs, const Point &rhs);
friend bool operator <(const Point &lhs, const Point &rhs);
/**
* Declare math operators
*/
friend Point operator +(const Point &lhs, const Point &rhs);
friend Point operator -(const Point &lhs, const Point &rhs);
/**
* Copy constructor
*/
Point(const Point& t);
/**
* Copy assignment
*/
Point &operator =( const Point& rhs );
private:
double x;
double y;
};
#endif /* POINT_H_ */
I was trying to overload assignment operator. Given
Point p1(1,2,3);
Point p2(1,2,3);
Point p3 = p1 + p2;
Point p4 = 22;
cout<< p4;
Here is my full code:
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
class Point{
private:
int m_x, m_y, m_z;
public:
Point(int x=0, int y = 0, int z = 0):m_x(x), m_y(y), m_z(z)
{
}
friend Point operator+(Point &p1, Point &p2);
friend ostream& operator<<(ostream &out, Point &p);
Point operator=(int val);
};
Point operator+(Point &p1, Point &p2){
return Point(p1.m_x+p2.m_x , p1.m_y+ p2.m_y , p1.m_z+p2.m_z);
}
ostream& operator<<(ostream &out, Point &p){
out<<"output: "<<p.m_x<<" "<<p.m_y<<" "<< p.m_z<<'\n';
return out;
}
Point Point::operator=(int val){
return Point(val, val, val);
}
int main(){
Point p1(1,2,3);
Point p2(1,2,3);
Point p3 = p1 + p2;
Point p4 = 22;
cout<< p4;
}
I can't insert the value 22 or any value in m_x, m_y ,m_z. How can I solve the line:
Point p4 = 22;
The are 2 different problems here.
Point p4 = 22;
This is not an assignment, it's actually a call to a constructor. Since you declared your constructor that takes 3 ints with default values, it can be called with 1, 2 or 3 values.
So it's equivalent of doing either of these two
Point p4(22, 0, 0);
Point p4(22);
If you want to use the assignment operator you need to write
Point p4;
p4 = 22;
But here we run in to the second problem, your assignment operator creates a new Point and returns it by value. What you want to do is modify the existing one.
Point& Point::operator=(int val){ // Return by reference
m_x = m_y = m_z = val;
return *this;
}
And you don't need to make the + operation a friend function.
using namespace std;
class Point {
public:
Point() {}
Point(int x , int y , int z ) :m_x(x), m_y(y), m_z(z)
{
}
Point& operator+(const Point &p1);
friend ostream& operator<<(ostream &out, Point &p);
Point& operator=(int val);
private:
int m_x, m_y, m_z;
};
Point& Point::operator+(const Point& p1)
{
Point temp;
temp.m_x = this->m_x + p1.m_x;
temp.m_y = this->m_y + p1.m_y;
temp.m_z = this->m_z + p1.m_z;
return temp;
}
ostream& operator<<(ostream &out, Point &p) {
out << "output: " << p.m_x << " " << p.m_y << " " << p.m_z << '\n';
return out;
}
Point& Point::operator=(int val) { // Return by reference
m_x = m_y = m_z = val;
return *this;
}
int main() {
Point p1(1, 2, 3);
Point p2(1, 2, 3);
Point p3 = p1 + p2;
Point p4;
p4 = 22;
cout << p4;
}
I've been having trouble trying to implement objects from class Cart_Vector in class Cart_Point. My compiler has been listing the following errors and I can't seem to fix them:
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
'Cart_Vector' does not name a type
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
'Cart_Vector' does not have a type
x = p1.x + v1.x; request for member 'x' in 'v1', which is of non-class
type 'const int'
y = p1.y + v1.y; request for member 'y' in 'v1', which is of non-class
type 'const int'
return Cart_Vector(x,y); 'Cart_Vector' was not declared in this scope
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2)
{
cout << "p1:(" << p1.x << ", " << p1.y << ")" << endl;
cout << "p2:(" << p2.x << ", " << p2.y << ")" << endl;
return p1,p2;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
Cart_Vector operator<<(const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
Cart_Vector Cart_Vector::operator<<(const Cart_Vector&v1)
{
cout <<"v1: <" << v1.x << ", " << ">" << endl;
return v1;
//this function should just print v1
}
//TestCheckpoint1.cpp file below
int main()
{
//I haven't finished the main function to test all the functions yet
return 0;
}
split your code in different files but your implementation of operator << is wrong , consider following code , its just a hint to help
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
friend std::ostream& operator<<( std::ostream& out,const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
std::ostream& operator<<(std::ostream &out, const Cart_Vector&v1)
{
out <<"v1: <" << v1.x << ", " << ">" << endl;
return out;
//this function should just print v1
}
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend std::ostream& operator<<(std::ostream& out , const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
std::ostream& operator<<(std::ostream &out, const Cart_Point&p1)
{
// Since operator<< is a friend of the Cart_Point class, we can access Point's members directly.
out << "p:(" << p1.x << ", " << p1.y << ")" << endl;
return out;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Point(x,y);
//this function should make a new Cart_Vector
}
//TestCheckpoint1.cpp file below
int main()
{
Cart_Point point1(2.0, 3.0);
std::cout << point1;
//I haven't finished the main function to test all the functions yet
return 0;
}
Wandbox :
Do yourself a favor and split your code in different files,at least one .h for Cart_Vector, one .h for Cart_Point, and one .cpp for the test script (main). You can correct this code to make it work (just swap the order of the two classes), if you correct other errors too, like in the overloading of the operator "-".
The point here is that if you start coding in this way, when you start programming complex projects you will find yourself in great difficulties. Coding one public (non-inner) class-per file is like applying Single Responsibility Principle for files too. I would say that also a file should have only one reason to change, and this has great benefits in readability and when will you perform version control.
Cart_Vector and Cart_point need each other. So you need to implement these classes in separate header files. Do not forget include them. Also in here ;
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
//return Cart_Vector(x,y);
return Cart_Pointer(x,y);
//this function should make a new Cart_Vector
}
You can not access non-const elements of const object and you can not call non-const functions. You can pass these objects by value if you want it.
I'm having an issue with the inheritance of my operator overloading functions in my derived class.
#pragma once
#include "Math.hpp"
using namespace Math;
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
float &operator[](const char &) const;
Euler &operator=(const Euler &);
Euler &operator+=(const Euler &);
Euler &operator-=(const Euler &);
Euler &operator*=(const float &);
Euler &operator/=(const float &);
Euler operator+(const Euler &) const;
Euler operator-(const Euler &) const;
Euler operator*(const float &) const;
Euler operator/(const float &) const;
bool operator==(const Euler &) const;
bool operator!=(const Euler &) const;
bool IsValid() const;
void Clear();
};
inline Euler::Euler()
{
x = y = z = 0.f;
}
inline Euler::Euler(const float &_x, const float &_y, const float &_z)
{
x = _x;
y = _y;
z = _z;
}
inline float &Euler::operator[](const char &c) const
{
return ((float *)this)[c];
}
inline Euler &Euler::operator=(const Euler &e)
{
x = e.x;
y = e.y;
z = e.z;
return *this;
}
inline Euler &Euler::operator+=(const Euler &e)
{
x += e.x;
y += e.y;
z += e.z;
return *this;
}
inline Euler &Euler::operator-=(const Euler &e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return *this;
}
inline Euler &Euler::operator*=(const float &e)
{
x *= e;
y *= e;
z *= e;
return *this;
}
inline Euler &Euler::operator/=(const float &e)
{
x /= e + M_FLT_EPSILON;
y /= e + M_FLT_EPSILON;
z /= e + M_FLT_EPSILON;
return *this;
}
inline Euler Euler::operator+(const Euler &e) const
{
return Euler(x + e.x, y + e.y, z + e.z);
}
inline Euler Euler::operator-(const Euler &e) const
{
return Euler(x - e.x, y - e.y, z - e.z);
}
inline Euler Euler::operator*(const float &f) const
{
return Euler(x * f, y * f, z * f);
}
inline Euler Euler::operator/(const float &f) const
{
return Euler(x / (f + M_FLT_EPSILON), y / (f + M_FLT_EPSILON), z / (f + M_FLT_EPSILON));
}
inline bool Euler::operator==(const Euler &e) const
{
return e.x == x && e.y == y && e.z == z;
}
inline bool Euler::operator!=(const Euler &e) const
{
return e.x != x || e.y != y || e.z != z;
}
inline bool Euler::IsValid() const
{
using namespace std;
return isfinite(x) && isfinite(y) && isfinite(z);
}
inline void Euler::Clear()
{
x = y = z = 0.f;
}
class Vector : public Euler
{
public:
using Euler::Euler;
void Rotate(const Angle &);
void Rotate2D(const float &);
float Length() const;
float LengthSqr() const;
float Length2D() const;
float Length2DSqr() const;
float DistTo(const Vector &) const;
float DistToSqr(const Vector &) const;
};
inline float Vector::Length() const
{
return Sqrt((x * x) + (y * y) + (z * z));
}
inline float Vector::LengthSqr() const
{
return (x * x) + (y * y) + (z * z);
}
inline float Vector::Length2D() const
{
return Sqrt((x * x) + (y * y));
}
inline float Vector::Length2DSqr() const
{
return (x * x) + (y * y);
}
inline float Vector::DistTo(const Vector &v) const
{
return (*this - v).Length();
}
inline float Vector::DistToSqr(const Vector &v) const
{
return (*this - v).LengthSqr();
}
The code shown below contains an error in the distto and DistToSqr function wherein it calculates (*this - v) as the superclass Euler and therefore cannot find the length function.
I was wondering why this would be as this code compiles on my laptop and not my desktop.
I'd be grateful if anyone could show me why this code doesn't work and what is the best course in fixing it.
It seems like doing this is a plausible way to fix it.
inline float Vector::DistTo(const Vector &v) const
{
Vector tmp = (*this - v);
return tmp.Length();
}
Still wondering if this is the best option to fix it though.
I'm going to assume that it is likely that Euler is always used as a base type of a more specific type? If so, you can might be able to solve this using the CRTP pattern. Here is a subset of your code in this style:
#include <cmath>
template <typename Derived>
class Euler
{
public:
float x, y, z;
Euler();
Euler(const float &, const float &, const float &);
template <typename T>
Derived & operator-=(Euler<T> const &);
template <typename T>
Derived operator-(Euler<T> const &) const;
private:
Derived & derived() const {
return static_cast<Derived &>(*this);
}
Derived const & derived() {
return static_cast<Derived const &>(*this);
}
};
template <typename Derived>
Euler<Derived>::Euler() : x(0), y(0), z(0)
{}
template <typename Derived>
Euler<Derived>::Euler(const float &_x, const float &_y, const float &_z)
: x(_x), y(_y), z(_z)
{}
template <typename Derived>
template <typename T>
Derived & Euler<Derived>::operator-=(Euler<T> const & e)
{
x -= e.x;
y -= e.y;
z -= e.z;
return derived();
}
template <typename Derived>
template <typename T>
Derived Euler<Derived>::operator-(Euler<T> const & e) const
{
return Derived(x - e.x, y - e.y, z - e.z);
}
class Vector : public Euler<Vector>
{
public:
using Euler<Vector>::Euler;
float Length() const;
float DistTo(const Vector &) const;
};
inline float Vector::Length() const
{
return std::sqrt(x * x + y * y + z * z);
}
inline float Vector::DistTo(const Vector & v) const
{
return (*this - v).Length();
}
I'm working on an assignment for my C++ class and have run into a little problem when running the program. I get an error stating Unhandled exception at 0x000944C8 in Pog11.exe: 0xC0000005: Access violation writing location 0x00000000. while debugging. The goal is to read in the int degree of a polynomial, as well as the double coefficients.
here is the .h file that I was supplied:
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include<iostream>
using std::ostream;
using std::istream;
using std::cerr;
using std::endl;
class Polynomial
{
friend ostream& operator<<( ostream& left , const Polynomial& right);
friend istream& operator>>( istream& left , Polynomial& right );
public:
Polynomial();
Polynomial( int degree, const double* coefficients );
Polynomial( const Polynomial& );
~Polynomial();
const Polynomial& operator=( const Polynomial& deg);
bool operator==( const Polynomial& deg ) const;
void setDegree(int d);
int getDegree() const;
private:
int degree;
double* coefficients;
};
#endif
And here is the segment of code that is causing the error:
istream& operator>>(istream& left, Polynomial& right)
{
int tmp;
left >> tmp;
right.setDegree(tmp);
int i = 0;
while (i<=right.getDegree())
{
double co;
left >> co;
right.coefficients[i] = co;
i++;
}
return left;
}
Specifically the right.coefficients[i]=co; line is what causes the program to crash.
Here are the constructors for the class:
#include "Polynomial.h"
Polynomial::Polynomial() :degree(0), coefficients(0)
{
degree = 0;
coefficients = new double[degree];
}
Polynomial::Polynomial(int deg, const double* coefficients)
{
if (deg < 0)
{
degree = 0;
}
else
{
degree = deg;
}
coefficients = new double [degree];
}
Polynomial::Polynomial(const Polynomial& deg)
{
if (deg.getDegree() <= 0)
{
setDegree(0);
}
else
{
setDegree(deg.getDegree());
for (int i = 0; i < degree; i++)
{
coefficients[i] = deg.coefficients[i];
}
}
}
There's code missing - e.g. the implementation of the constructor of the Polynomial object.
I'm pretty sure that your error is that you have not allocated (enough) memory for the coefficients data member. There must be a
coefficients = new double[number_of_coeffs]
somewhere in your code.
EDIT
There's a number of points where you need to do this: where the degree of the polynomial is (re)set. Because then you know the degree of the polynomial:
Here you must copy the elements passed:
Polynomial( int degree, const double* coefficients ):
coefficients( new double[degree] ), degree( degree )
{
::memcpy(this->coefficients, coefficients, degree * sizeof(double));
}
and in this one, the degree of the polynomial changes - so your coefficients array must be modified accordingly.
Polynomial::setDegree( int degree ) {
// first delete the old coefficients
delete [] coeffs;
// and make a new array
this->degree = degree;
this->coefficients = new double[ this->degree ];
// initialize the coefficients
..
}
Similar actions have to be done in the copy constructor and the assignment operator.
Finally: you might be better off using std::vector<double> which basically does all the memory management for you. See http://en.cppreference.com/w/cpp/container/vector