Pretty new to C++, I have been following the intermediate tutorials at 3DBuzz.com, and trying to experiment with their tasks.
Current tutorial is on classes: http://www.3dbuzz.com/vbforum/sv_showvideo.php?v=37
I am trying to overload the &operator << to output my 'Point' as a stream when I want. The relevant part of the video starts at 39:00.
As far as I can tell my code is syntactically identical (though I am new so I'm probably missing something) but I get the error:
1>c:\users\jack\documents\visual studio 2010\projects\myfirstgame\myfirstgame\main.cpp(88): error C2146: syntax error : missing ';' before identifier 'myPoint
I realise that I declare the instance Point &myPoint in the operator overload function.. but I don't know where else I could do it so the compiler knows what it is.. if that makes sense.
Any help is appreciated! Thanks
#include <iostream>
#include <cmath>
using namespace std;
class Point
{
public:
Point(float f_x = 0.0, float f_y = 0.0, float f_z = 0.0);
~Point();
void SetXYZ(float X, float Y, float Z);
void SetX(float X);
void SetY(float Y);
void SetZ(float Z);
void GetXYZ(float &X, float &Y, float &Z);
float GetX();
float GetY();
float GetZ();
private:
float x, y, z;
protected:
};
Point::Point(float f_x, float f_y, float f_z)
{
cout << "Constructor with ARGUMENTS!" << endl;
x = f_x;
y = f_y;
z = f_z;
}
void Point::GetXYZ(float &X, float &Y, float &Z)
{
X = GetX();
Y = GetY();
Z = GetZ();
}
float Point::GetX()
{
return x;
}
float Point::GetY()
{
return y;
}
float Point::GetZ()
{
return z;
}
void Point::SetXYZ(float X,float Y, float Z)
{
SetX(X);
SetY(Y);
SetZ(Z);
}
void Point::SetX(float X)
{
x = X;
}
void Point::SetY(float Y)
{
y = Y;
}
void Point::SetZ(float Z)
{
z = Z;
}
Point::~Point()
{
cout << "We're in the destructor" << endl;
}
ostream &operator <<(ostream &stream, Point &myPoint)
{
stream << myPoint.GetX() << " " << myPoint.GetY() << " " myPoint.GetZ();
return stream;
}
void main()
{
float x, y, z; //Declaring floats for use in GetXYZ()
Point myLocation (1,2,-1); //Creating instance and using Point(...) function
cout << myLocation.GetX() << myLocation.GetY() << myLocation.GetZ() <<endl; // Getting xyz values and printing
myLocation.SetXYZ(2,3,-4); //Testing SetXYZ function
cout << myLocation.GetX() << myLocation.GetY() << myLocation.GetZ() <<endl; // Getting xyz values and printing
myLocation.GetXYZ(x, y, z);
cout << x << " " << y << " " << z << endl;
cout << myLocation;
system("PAUSE");
}
EDIT: Unbelievable response! Love this site already. Thanks everyone who spotted this ^^
You are missing << in :
stream << myPoint.GetX() << " " << myPoint.GetY() << " " myPoint.GetZ();
^^
At line 88 you should add << before myPoint.GetZ();
Your code:
stream << myPoint.GetX() << " " << myPoint.GetY() << " " myPoint.GetZ();
Correction:
stream << myPoint.GetX() << " " << myPoint.GetY() << " " << myPoint.GetZ();
See the difference in between these two?
stream << myPoint.GetX() << " " << myPoint.GetY() << " " myPoint.GetZ();
stream << myPoint.GetX() << " " << myPoint.GetY() << " " << myPoint.GetZ();
Here is the problem: stream << myPoint.GetX() << " " << myPoint.GetY() << " " myPoint.GetZ(); You are missing << between the last " " and the last myPoint.
Here you go:
ostream &operator <<(ostream &stream, Point &myPoint) { stream << myPoint.GetX() << " " << myPoint.GetY() << " "<< myPoint.GetZ(); return stream; }
Note the extra "<<" before myPoint.GetZ();
Related
In my program I have created a constructor called Point with two values. I also have a set, get, scale and translate function. I'm trying to create a function that allows me to get the distance between the object and another point. I'm have trouble with it though any help would be brilliant.
#ifndef POINTMODEL
#define POINTMODEL
#define POINTDEB UG
#include <iostream>
#include <string.h>
using namespace std;
class Point {
public:
Point(void);
Point(double anX, double aY);
~Point();
void setPoint(double anX, double aY);
double getX();
double getY();
double scaleX(double theX);
double scaleY(double theY);
void translate(double theX, double theY);
void distance(const Point& aPoint);
protected:
private:
double theX;
double theY;
};
inline Point::Point(void)
{
theX = 1;
theY = 1;
cout << "\n The default constructor was called" << endl;
}
inline Point::Point(double anX, double aY)
{
cout << "\n regular constructor called";
}
inline Point::~Point()
{
cout << "\n the destructor was called" << endl;
}
inline void Point::setPoint(double anX, double aY)
{
theX = anX;
theY = aY;
}
inline double Point::getX()
{
return theX;
}
inline double Point::getY()
{
return theY;
}
inline double Point::scaleX(double theX)
{
return theX;
}
inline double Point::scaleY(double theY)
{
return theY;
}
inline void Point::translate(double offSetX, double offSetY)
{
cout << "X is translated by : " << offSetX << endl;
cout << "Y is translated by : " << offSetY << endl;
}
inline void Point::distance(const Point& aPoint)
{
}
#endif
Cpp file:
#include "Point.h"
using namespace std;
int main(void)
{
cout << "\n main has started" << endl;
//Point myPoint;
Point myPoint(1, 1);
myPoint.setPoint(1, 1);
cout << "\n The value for X is : " << myPoint.getX() << endl;
cout << "\n The value for Y is : " << myPoint.getY() << endl;
cout << "\n X scaled by 2 is : " << myPoint.scaleX(2) << endl;
cout << "\n Y scaled by 2 is : " << myPoint.scaleY(2) << endl;
myPoint.translate(2, 3);
cout << "\n main has finished" << endl;
return 0;
}
You need to make your Point::getX() and Point::getY() functions const like so:
inline double Point::getX() const
{
return theX;
}
If they are not const you cannot call them when the parameter is a const reference.
Then the distance is (changed return from void to double):
double distance(const Point & aPoint) const
{
const double x_diff = getX() - aPoint.getX();
const double y_diff = getY() - aPoint.getY();
return std::sqrt(x_diff * x_diff + y_diff * y_diff);
}
I have deliberately not used std::pow since the exponent is 2.
You also need to include <cmath> for std::sqrt.
I am using the following classes in my code
class pos2d
{
float x, y;
public:
float getx() const;
float gety() const;
//int getz() const; //How to avoid??
};
class pos3d
{
float x, y, z;
public:
float getx() const;
float gety() const;
float getz() const;
};
template<class T, class P>
class entity
{
T type;
P position;
public:
void print() const;
};
My print function in class entity is as follows
template<class T, class P>
void entity<T, P>::print() const
{
if (type == 1 || type == 'A')
cout << "Object is of type " << type << " and has coordinates as (" << position.getx() << ", " << position.gety() << ", " << position.getz() << ")\n\n"; //Avoid getz in pos2d
else if (type == 2 || type == 'B')
cout << "Object is of type " << type << " and has coordinates as (" << position.getx() << ", " << position.gety() << ")\n\n";
}
Note, Type value changes depending of whether class is pos2d or pos2d.
During compilation I get the following error:
Error C2039 'getz': is not a member of 'pos2d' Project1
I am aware that using a common get() function would solve this but i wish to be able to use getz() in my code without having it as part of another common function.
The problem is if you pass pos2d as template parameter the line
cout << "Object is of type " << type << " and has coordinates as (" << position.getx() << ", " << position.gety() << ", " << position.getz() << ")\n\n";
is still instantiated (if is done at runtime), the function cannot be resolved.
The usual way is to use specializations (Type parameter can be omitted):
template<class P>
class entity
{
P position;
public:
void print() const;
};
template<>
void entity<pos3d>::print() const
{
cout << "Object is of type pos3d and has coordinates as ("
<< position.getx() << ", " << position.gety() << ", " << position.getz() << ")\n\n";
}
template<>
void entity<pos2d>::print() const
{
cout << "Object is of type pos2d and has coordinates as ("
<< position.getx() << ", " << position.gety() << ")\n\n";
}
I see 2 simple ways to implement this:
- Make print() a member function of posX class.
- Specialize print() function in entity class.
#include <iostream>
class pos2d
{
float x, y;
public:
float getx() const { return x; }
float gety() const { return y; }
void print() const
{
std::cout << "Object is of type and has coordinates as (" << getx() << ", " << gety() << ")\n\n";
}
};
class pos3d
{
float x, y, z;
public:
float getx() const { return x; }
float gety() const { return y; }
float getz() const { return z; }
void print() const
{
std::cout << "Object is of type and has coordinates as (" << getx() << ", " << gety() << ", " << getz() << ")\n\n";
}
};
template <class P>
class entity
{
P position;
public:
void print() const { position.print(); }
void print_specialized() const;
};
template <>
void entity<pos3d>::print_specialized() const {
std::cout << "Object is of type and has coordinates as (" << position.getx() << ", " << position.gety() << ", " << position.getz() << ")\n\n";
}
template <>
void entity<pos2d>::print_specialized() const {
std::cout << "Object is of type and has coordinates as (" << position.getx() << ", " << position.gety() << ")\n\n";
}
int main() {
entity<pos2d> e;
e.print();
e.print_specialized();
entity<pos3d> e2;
e2.print();
e2.print_specialized();
return 0;
}
I am having issues displaying coordinates that are read into a class. This is my first time using classes so please be understanding!
Here is what I have so far:
#include <iostream>
using namespace std;
class Vector{
private:
float x;
float y;
public:
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
Vector(){}
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
};
int main()
{
Vector v1(0.5, 0.5);
cout << "v1 ";
v1.display();
system("pause");
return 0;
}
It prints
v1 (-1.07374e+008,-1.07374e+008)
Your problem is that you are not printing out the coordinates of the Vector you created in main() but a default created one in your function. Instead of
float display()
{
Vector v;
cout << "(" << v.x << "," << v.y << ")" << endl;
return 0;
}
You need
float display()
{
//Vector v; remove this
cout << "(" << x << "," << y << ")" << endl;
// no v.x no v.y
return 0;
}
I suggest you change the default constructor to
Vector() : x(0), y(0) {}
So it would have printed
v1 (0,0)
You should also change
Vector(float f1, float f2)
{
x=f1;
y=f2;
}
To
Vector(float f1, float f2) : x(f1), y(f2) {}
As it is a good habit to get into. This can save resources and CPU cycles when dealing with non POD types. For more information see Why should I prefer to use member initialization list?
the Vector v; line is a mistake. You are basically creating a new uninitialized vector instead of crating your own instance.
one correction would be:
int display()
{
cout << "(" << x << "," << y << ")" << endl;
return 0;
}
since x and y are member of this class
I get a linking error when i try to compile this code. I need to overload the output operator to display a three dimensional vector class I am not sure where to go from here any help is appreciated.
Vect3D.h
#ifndef VECT3D_H
#define VECT3D_H
#include <iostream>
class Vect3D
{
public:
Vect3D();
Vect3D(double xVal, double yVal, double zVal);
double getX() const { return x; }
double getY() const { return y; }
double getZ() const { return z; }
double magnitude() const { return sqrt(x*x + y*y + z*z); }
friend ostream& operator<<(ostream& os, const Vect3D& out);
void setX(double xVal) { x = xVal; }
void setY(double yVal) { y = yVal; }
void setZ(double zVal) { z = zVal; }
private:
double x;
double y;
double z;
};
ostream& operator<<(ostream& os, const Vect3D& out)
{
os << "(" << out.x << ", " << out.y << ", " << out.z << ")";
return os;
}
#endif
Vect3D.cpp
using namespace std;
#include "Vect3D.h"
Vect3D::Vect3D()
: x(0), y(0), z(0)
{ } // empty body
Vect3D::Vect3D(double xVal, double yVal, double zVal)
: x(xVal), y(yVal), z(zVal)
{ } // empty body
TestCode.cpp
#include <iostream>
#include <cmath>
#include <string>
#include <sstream>
using namespace std;
#include "Vect3D.h"
int main()
{
Vect3D v;
const Vect3D zero;
Vect3D v1(1, 2, 3), v2(7.5, 8.5, 9.5);
const Vect3D con(4, 5, 6);
cout << "Testing overload of << operator" << endl;
cout << v1;
cout << endl;
cout << "Should be:" << endl;
cout << "(" << v1.getX() << ", " << v1.getY() << ", " << v1.getZ() << ")" << endl << endl;
cout << "Testing chaining of overload of << operator" << endl;
cout << v1 << endl;
cout << "Should be:" << endl;
cout << "(" << v1.getX() << ", " << v1.getY() << ", " << v1.getZ() << ")" << endl << endl;
cout << "Testing overload of << operator for const Vect3D's" << endl;
cout << con << endl;
cout << "Should be:" << endl;
cout << "(" << con.getX() << ", " << con.getY() << ", " << con.getZ() << ")" << endl << endl;
cout << "Testing ostream parameter passing for the << operator" << endl;
stringstream sout;
sout << con;
string s = sout.str();
cout << s << endl;
cout << "Should be: " << endl;
cout << "(4, 5, 6)" << endl << endl;
cout << endl << endl;
return 0;
}
Errors:
Error 1 error LNK2005: "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,class Vect3D const &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#ABVVect3D###Z) already defined in TestCode.obj G:\overloadAssignment\overloadAssignment\Vect3D.obj
Error 2 error LNK1169: one or more multiply defined symbols found G:\overloadAssignment\Debug\overloadAssignment.exe 1
This directive has been used assiduously in other sections of this tutorial. When the preprocessor finds an #include directive it replaces it by the entire content of the specified header or file. See more information here.
So you have ostream& operator<<(ostream& os, const Vect3D& out) definition in Vect3D.h and you include this file in both TestCode.cpp and Vect3D.cpp. Thus you compile this function twice in Vect3D.obj and TestCode.obj. And when you try to link program, linker says that you have multiple definitions, and linker does not know what definition is right.
You need to put your implementation in Vect3D.cpp to compile it just once.
Vect3D.h
#ifndef VECT3D_H
#define VECT3D_H
#include <iostream>
class Vect3D
{
public:
Vect3D();
Vect3D(double xVal, double yVal, double zVal);
double getX() const { return x; }
double getY() const { return y; }
double getZ() const { return z; }
double magnitude() const { return sqrt(x*x + y*y + z*z); }
friend ostream& operator<<(ostream& os, const Vect3D& out);
void setX(double xVal) { x = xVal; }
void setY(double yVal) { y = yVal; }
void setZ(double zVal) { z = zVal; }
private:
double x;
double y;
double z;
};
ostream& operator<<(ostream& os, const Vect3D& out);
#endif
Vect3D.cpp
using namespace std;
#include "Vect3D.h"
Vect3D::Vect3D()
: x(0), y(0), z(0)
{ } // empty body
Vect3D::Vect3D(double xVal, double yVal, double zVal)
: x(xVal), y(yVal), z(zVal)
{ } // empty body
ostream& operator<<(ostream& os, const Vect3D& out)
{
os << "(" << out.x << ", " << out.y << ", " << out.z << ")";
return os;
}
I am having trouble with the output part of the problem, I am getting errors on the lines that say bottom right, top left, and dimension. What am i doing wrong?
I have tried many things and I just do not know how to get it to work correctly, and we have not gone over anything like this kind of output in class:
#include <iostream>
#include <cmath>
using namespace std;
class Point
{
private:
double px;
double py;
public:
void setX(const double x);
void setY(const double y);
double getX() const;
double getY() const;
};
class Triangle
{
private:
Point blPoint;
double length, height;
public:
// member functions
void setBottomLeftX(const double x);
void setBottomLeftY(const double y);
void setLength(const double inLength);
void setHeight(const double inHeight);
Point getBottomLeft() const;
Point getBottomRight() const;
Point getTopLeft() const;
double getLength() const;
double getHeight() const;
double perimeter() const;
double hypotenuse() const;
void scaleLength(const double sx);
void scaleHeight(const double sy);
void display() const;
};
// FUNCTION PROTOTYPES GO HERE:
double read_triangle(Triangle & tri);
int main()
{
// Define local variables
Triangle tri;
double sx, sy;
//Prompt the user for triangle information and fill Class Triangle object, tri,
//with this information
read_triangle(tri);
// Display triangle information
tri.display();
// Prompt and read scale factors to change length and height
cout << "Enter scale factor in x direction: ";
cin >> sx;
cout << "Enter scale factor in y direction: ";
cin >> sy;
// Apply scale factors
tri.scaleLength(sx);
tri.scaleHeight(sy);
// Display triangle information
tri.display();
return 0;
}
// FUNCTION DEFINITIONS GO HERE:
// CLASS MEMBER FUNCTION DEFINITINOS GO HERE:
void Point::setX(const double x)
{
px = x;
}
void Point::setY(const double y)
{
py = y;
}
double Point::getX() const
{
return (px);
}
double Point::getY() const
{
return (py);
}
void Triangle::setBottomLeftX(const double x)
{
/* INSERT YOUR CODE */
blPoint.setX(x);
}
void Triangle::setBottomLeftY(const double y)
{
/* INSERT YOUR CODE */
blPoint.setY(y);
}
void Triangle::setLength(const double inLength)
{
/* INSERT YOUR CODE */
length=inLength;
}
void Triangle::setHeight(const double inHeight)
{
/* INSERT YOUR CODE */
height=inHeight;
}
Point Triangle::getBottomLeft() const
{
/* INSERT YOUR CODE */
return (blPoint);
}
Point Triangle::getBottomRight() const
{
/* INSERT YOUR CODE */
Point getBottomRight;
double mx = (blPoint.getX()+ length);
getBottomRight.setX(mx);
return(getBottomRight);
}
Point Triangle::getTopLeft() const
{
/* INSERT YOUR CODE */
Point getTopLeft;
double my = (blPoint.getY()+ height);
getTopLeft.setY(my);
return (getTopLeft);
}
double Triangle::getLength() const
{
/* INSERT YOUR CODE */
return (length);
}
double Triangle::getHeight() const
{
/* INSERT YOUR CODE */
return (height);
}
double Triangle::hypotenuse() const
{
/* INSERT YOUR CODE */
//hypotenuse = (sqrt((height * height)+(length * length)));
return (sqrt((height * height)+(length * length)));
}
double Triangle::perimeter() const
{
/* INSERT YOUR CODE */
//perimeter = ((sqrt((height * height)+(length * length)))+ height + length);
return ((sqrt((height * height)+(length * length)))+ height + length);
}
void Triangle::scaleLength(const double scalefact)
{
/* INSERT YOUR CODE */
length = scalefact * length;
}
void Triangle::scaleHeight(const double scalefact)
{
/* INSERT YOUR CODE */
height = scalefact * height;
}
void Triangle::display() const
{
/* INSERT YOUR CODE */
cout <<"---------------------------------------" << endl;
cout << "Lower Left Vertex (" << blPoint.getX() << ", " << blPoint.getY() << ')' <<endl;
cout << "Top Left Vertex (" << blPoint.getX() << ", " << getTopLeft.getY() << ')' << endl;
cout << "Bottom Right Vertex (" << getBottomRight.getX() << ", " << blPoint.getY() << ')' << endl;
cout << "Dimensions (" << getBottomRight.getX()- blPoint.getX() << ", " << getTopleft.getY() - blPoint.getY() << ')' << endl;
cout << "Hypotenuse = " << hypotenuse() << endl;
cout << "Perimeter = " << perimeter() << endl;
cout <<"---------------------------------------" << endl;
}
double read_triangle(Triangle & tri)
{
/* INSERT YOUR CODE */
double x, y, inLength, inHeight;
cout << "Enter bottom left x coordinate: ";
cin >> x;
tri.setBottomLeftX(x);
cout << "Enter bottom left y coordinate: ";
cin >> y ;
tri.setBottomLeftY(y);
cout << "Enter length: ";
cin >> inLength;
tri.setLength(inLength);
cout << "Enter Height: ";
cin >> inHeight;
tri.setHeight(inHeight);
}
You are using the functions like they are variables you need to add () to call them correctly:
cout << "Top Left Vertex (" << blPoint.getX() << ", " << getTopLeft().getY() << ')' << endl;
^^
cout << "Bottom Right Vertex (" << getBottomRight().getX() << ", " << blPoint.getY() << ')' << endl;
^^
cout << "Dimensions (" << getBottomRight().getX()- blPoint.getX() << ", " << getTopLeft().getY() - blPoint.getY() << ')' << endl;
^^ ^^
Also, read_triangle does not have a return statement but you declare that it returns double. Flowing off the end of a value returning function is undefined behavior and therefore you can not rely on the results. It does not look like you are using the results so you may want to just change the function to return void and that will fix it.