i have the following Vector3D code, and for some reason cin is able to change the object values only once. do you have any idea why?
i guess it's something related to the 'const' definition but i'm not sure.
adding both code (partial) and test
// code:
class Vector3D
{
private:
double _x, _y, _z;
public:
Vector3D() : _x(0), _y(0), _z(0) {};
Vector3D(double x, double y, double z) : _x(x), _y(y), _z(z) {};
Vector3D(const double parm[DIMENSION]) : _x(parm[0]), _y(parm[1]),
_z(parm[2]) {};
const Vector3D operator+(const Vector3D &other) const;
Vector3D &operator+=(const Vector3D &other);
const double &operator[](int idx) const;
double &operator[](int idx);
friend ostream &operator<<(ostream &out, const Vector3D &c);
friend istream &operator>>(istream &in, Vector3D &c);
};
const Vector3D Vector3D::operator+(const Vector3D &other) const {
return Vector3D(*this) += other;
}
Vector3D &Vector3D::operator+=(const Vector3D &other) {
(*this)._x += other._x;
(*this)._y += other._y;
(*this)._z += other._z;
return *this;
}
const double &Vector3D::operator[](int idx) const {
assert(idx >= 0 && idx < DIMENSION);
switch (idx)
{
case 0:
return _x;
case 1:
return _y;
case 2:
return _z;
default:
return _x; // not reachable
}
}
double &Vector3D::operator[](int idx)
{
assert(idx >= 0 && idx < DIMENSION);
switch (idx)
{
case 0:
return _x;
case 1:
return _y;
case 2:
return _z;
default:
return _x; // not reachable
}
}
ostream &operator<<(ostream &out, const Vector3D &c)
{
out << c._x << " " << c._y << " " << c._z;
return out;
}
istream &operator>>(istream &in, Vector3D &c)
{
in >> c._x >> c._y >> c._z;
return in;
}
// test:
void readFromStreamTest(int &tests) {
std::stringstream os;
os << 8.0 << " " << 3.0 << " " << 4.0;
Vector3D a;
os >> a;
os << a; // "8 3 4" as should be
os.str(std::string());
os << 2.1 << " " << 3.1 << " " << 4.1;
os >> a;
os.str(std::string());
os << a;
if (os.str()!=("2.1 3.1 4.1"))
{
std::cerr << "failed. should be 2.1 3.1 4.1 but was " << a;
}
}
test results: "failed. should be 2.1 3.1 4.1 but was 8 3 4" (old values!!)
You cannot use a stringstream like that, after extracting the contain throw os >> you cannot again modify it by os.str(value) nor os << if you don't call os.clear() before, for instance
void readFromStreamTest(int &tests) {
std::stringstream os;
os << 8.0 << " " << 3.0 << " " << 4.0;
Vector3D a;
os >> a;
os.clear();
os << a; // "8 3 4" as should be
os.str(std::string());
os << 2.1 << " " << 3.1 << " " << 4.1;
os >> a;
os.str(std::string());
os.clear();
os << a;
if (os.str()!=("2.1 3.1 4.1"))
{
std::cerr << "failed. should be 2.1 3.1 4.1 but was " << a;
}
}
P.S. I modified your original code to make it compilable
Related
Conversion from SI to ImperialSystem is working but the reverse isnot working.
The error message:
static_cast: cannot convert from ImperialSystem to SI
code:
#include<iostream>
#define endl '\n'
using std::cout;
#define MTRTOFEETRATIO 3.28084;
/*
Write two classes to store distances in meter-centimeter and feet-inch systems respectively. Write conversions functions so that the program can convert
objects of both types.
*/
class SI;
class ImperialSystem {
private:
int mfeet;
int minch;
public:
ImperialSystem(int m, int cm) :mfeet{ m }, minch{ cm }{};
ImperialSystem(float dis) :mfeet{ static_cast<int>(dis) }, minch{ static_cast<int>((dis - mfeet) * 12) } {}
operator float() {
return mfeet + minch / 12.0;
}
operator SI();
friend std::ostream& operator <<(std::ostream& out, const ImperialSystem& dis);
};
class SI {
private:
int mmeter;
int mcentimeter;
public:
SI(int m, int cm) :mmeter{ m }, mcentimeter{ cm }{};
SI(float dis) :mmeter{ static_cast<int>(dis) }, mcentimeter{ static_cast<int>((dis - mmeter) * 12) } {}
operator ImperialSystem();
friend std::ostream& operator <<(std::ostream& out, const SI& dis);
};
std::ostream& operator <<(std::ostream& out, const SI& dis) {
out << " " << dis.mmeter << " m " << dis.mcentimeter << " cm ";
return out;
}
std::ostream& operator <<(std::ostream& out, const ImperialSystem& dis) {
out << " " << dis.mfeet << " ft " << dis.minch << " in ";
return out;
}
ImperialSystem::operator SI() {
double feet = mfeet + minch / 12;
double meter = feet / MTRTOFEETRATIO;
return meter;
}
SI::operator ImperialSystem() {
double meter = mmeter + mcentimeter / 100.0;
double feet = meter * MTRTOFEETRATIO;
return feet;
}
int main() {
SI s{ 20,35 };
cout << s << " = " << static_cast<ImperialSystem>(s) << endl;//this works
ImperialSystem i{ 10,11 };
cout << i << " = " << static_cast<SI>(i) << endl;//but this doesnot
return 0;
}
Remove,
operator float() {
return mfeet + minch / 12.0;
}
from your SI class.
This creates confusion in construction and casting in msvs and clang compiler.
If I have a vector like this:
struct vector3D {
float x;
float y;
float z;
};
vector3D aVector = { 3.4, 4.4, 9.3 }; // my vector
How can I cout the aVector to the console?
you can overload the insertion operator << to use for your objects:
struct vector3D {
float x;
float y;
float z;
friend ostream& operator<<(ostream& out, vector3D rhs){
out << "( " << rhs.x << ", " << rhs.y << ", " << rhs.z << " )" << endl;
return out;
}
};
now you can use cout to print your object values:
int main(){
vector3D v = {10, 20, 30};
cout << v << endl;
}
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 trying to implement comparison between different subclasses of the same base class. The comparison should return false if the two instances are of different subclass or return the actual comparison result if they are of the same subclass.
Check the last line in function main: although I have declared equalTo as virtual, only the equalTo method of the base class is called. What is my mistake?
Thanks in advance.
#include <iostream>
#include <fstream>
#include <cmath>
#include <limits>
#include <sstream>
#include <stdexcept>
#include <algorithm>
using namespace std;
bool fileInput = false, fileOutput = false;
class Point
{
public:
double x,y;
Point(){};
Point(double x1, double y1) {
x=x1;
y=y1;
}
bool operator==(Point other) const
{
return (abs(x - other.x) < numeric_limits<double>::epsilon()) and (abs(y - other.y) < numeric_limits<double>::epsilon());
}
};
class Shape
{
protected:
virtual double area() const
{
return 0;
}
virtual void print(std::ostream& os) const {}
virtual void read(std::istream& is) {}
public:
bool compare(Shape* other) {
return area() < other->area();
}
virtual bool equalTo(Shape other) const {
cout << "original";
return false;
}
friend std::ostream& operator<<(std::ostream &strm, const Shape &t)
{
t.print(strm);
return strm;
}
friend std::istream& operator>>(std::istream &strm, Shape &t)
{
t.read(strm);
return strm;
}
};
class Circle : public Shape
{
Point c;
double r;
double area() const
{
return M_PI * r * r;
}
void print(std::ostream &strm) const
{
strm << "Circle. Center coordinates: (" << c.x << "," << c.y << "). Radius: " << r << ". Area: " << area();
}
void read(std::istream &strm)
{
if (!fileInput) cout << "Enter Circle\nCenter: ";
strm >> c.x >> c.y;
if (!fileInput) cout << "Radius: ";
strm >> r;
if (r<0)
throw std::invalid_argument( "The radius cannot be negative." );
}
public:
Circle() {}
Circle(Point x, double y)
{
c = x;
r = y;
}
bool equalTo(Shape other1) const
{
Circle* other = dynamic_cast<Circle*>(&other1);
if (other == 0) return false;
return (c == other->c) and (abs(r - other->r)<numeric_limits<double>::epsilon());
}
};
class Hexagon : public Shape
{
Point c;
double r;
double area() const
{
return 1.5 * sqrt(3) * r * r;
}
void print(std::ostream &strm) const
{
strm << "Hexagon. Center coordinates: (" << c.x << "," << c.y << "). Circumcircle radius: " << r << ". Area: " << area();
}
void read(std::istream &strm)
{
if (!fileInput) cout << "Enter Hexagon\nCenter: ";
strm >> c.x >> c.y;
if (!fileInput) cout << "Circumcircle radius: ";
strm >> r;
if (r<0)
throw std::invalid_argument( "The circumcircle radius cannot be negative." );
}
public:
Hexagon() {}
Hexagon(Point x, double y)
{
c = x;
r = y;
}
bool equalTo(Shape other1) const
{
Hexagon* other = dynamic_cast<Hexagon*>(&other1);
if (other == 0) return false;
return (c == other->c) and (abs(r - other->r)<numeric_limits<double>::epsilon());
}
};
int main()
{
Shape c1 = Circle(Point(0,0), 3);
Shape c2 = Circle(Point(0,0), 3);
Shape c3 = Hexagon(Point(0,0), 3);
cout << "circles: " << c1.equalTo(c2) << endl << "diff: " << c1.equalTo(c3) << endl;
}
This is slicing, when you assign objects to object of type Shape - object was sliced to Shape. Use pointers, or may be references.
Circle p1(Point(0, 0), 3);
Circle p2(Point(0, 0), 3);
Hexagon h1(Point(0, 0), 3);
Shape& c1 = p1;
Shape& c2 = p2;
Shape& c3 = h1;
When you copy-construct a Shape out of a derived class, the object will be sliced so that only the Shape part of it is preserved. Then when you call equalTo, the function is statically bound.
In order to call the derived versions, make c1 and friends into Shape&.
I am doing a tutorial to learn about operator overloading and while writing the code as in the book, i got errors in the following section:
std::ostream &operator<<(std::ostream &outst, const AC_current &c)
{
outst << std::setiosflags(std::ios::fixed)<<std::setprecision(2);
outst << "(" << std::setw(6) << c.mag; //----->'mag' is a private member of 'AC_current'
outst << ", " << std::setw(6) << c.phase<<(char)248<< ") A"; //--->'phase' is a private member of 'AC_current'
return outst;
}
I defined it as a friend function, but its not working. What am I doing wrong?
P.S.This is the complete code.
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
const double Deg2Rad = 2*M_PI/360;
const double Rad2Deg = 360/(2*M_PI);
class AC_current
{
private:
double mag, phase;
double real, imag;
void setRect();
void setPolar();
public:
AC_current(double m=0, double p=0)
{
mag = m; phase = p; setRect();
}
AC_current operator-(const AC_current & c) const;
AC_current operator+(const AC_current & c) const;
AC_current operator*(double) const;
int getCoord();
friend std::istream &operator >> (std::istream &inst, AC_current &c);
friend std::ostream &operator << (std::ostream &outst, AC_current &c);
};
int AC_current::getCoord()
{
int selection;
do
{
std::cout << "\n Select: \n\t1) AC current in polar coordinates ";
std::cout << "\n\t2) AC current in rectangular coordinates ";
std::cout << "\n\t Enter selection: ";
std::cin >> selection;
} while ((selection!=1)&&(selection!=2));
return selection;
}
void AC_current::setRect()
{
real= mag*cos(phase*Deg2Rad);
imag=mag*sin(phase*Deg2Rad);
}
void AC_current::setPolar()
{
mag=sqrt(real*real+imag*imag);
if (!((real==0)&&(imag==0)))
{
phase=atan(imag/real)*Rad2Deg;
}
else
phase=0;
}
AC_current AC_current::operator-(const AC_current &c) const
{
AC_current temp;
double treal, timag;
treal = mag*cos(phase*Deg2Rad)-c.mag*cos(c.phase*Deg2Rad);
timag = mag*sin(phase*Deg2Rad)-c.mag*sin(c.phase*Deg2Rad);
temp.mag = sqrt(treal*treal+timag*timag);
if (!((treal==0)&&(timag==0)))
{
temp.phase = atan(timag/treal)*Rad2Deg;
}else temp.phase=0;
return temp;
}
AC_current AC_current::operator+(const AC_current &c) const
{
AC_current temp;
double treal, timag;
treal = mag*cos(phase*Deg2Rad)+c.mag*cos(c.phase*Deg2Rad);
timag = mag*sin(phase*Deg2Rad)+c.mag*sin(c.phase*Deg2Rad);
temp.mag = sqrt(treal*treal+timag*timag);
if (!((treal==0)&&(timag==0)))
{
temp.phase = atan(timag/treal)*Rad2Deg;
}else temp.phase=0;
return temp;
}
AC_current AC_current::operator*(double r) const
{
AC_current temp;
temp.mag = mag*r;
temp.phase = phase;
temp.setRect();
return temp;
}
std::istream &operator>>(std::istream &inst, AC_current &c)
{
int choice=c.getCoord();
if (choice==1)
{
std::cout << "\nEnter magnitude: ";
inst >> c.mag;
std::cout << "\nEnter phase shift: ";
inst >> c.phase;
c.setRect();
}
else if(choice == 2)
{
std::cout << "\nEnter real part: ";
inst >> c.real;
std::cout << "\nEnter imaginary part: ";
inst >> c.imag;
c.setPolar();
}
return inst;
}
std::ostream &operator<<(std::ostream &outst, const AC_current &c)
{
outst << std::setiosflags(std::ios::fixed)<<std::setprecision(2);
outst << "(" << std::setw(6) << c.mag;
outst << ", " << std::setw(6) << c.phase<<(char)248<< ") A";
return outst;
}
int menu()
{
int selection;
do
{
std::cout << "\n\n\tSelect operation:" << std::endl;
std::cout << "\n\n 1)Add currents" << std::endl;
std::cout << "\n\n 2)Substract currents" << std::endl;
std::cout << "\n\n 3)Multiply current by resistance" << std::endl;
std::cout << "\n\n 4)Exit" << std::endl;
std::cout << "\n\n Enter selection (1-4) => ";
std::cin >> selection ;
} while (selection<1||selection>4);
return selection;
}
int main ()
{
AC_current c1,c2;
int operation;
std::cin >> c1 >> c2;
while (operation !=4) {
operation = menu();
switch (operation) {
case 1:
std::cout << "\n\tc1+c2 = " << (c1+c2);
break;
case 2:
std::cout << "\n\tc1-c2 = " << (c1-c2);
break;
case 3:
double r;
std::cout <<"\nEnter resistance : ";
std::cin >> r;
std::cout << "\n\tc1*R = " << (c1*r);
break;
case 4:
break;
}
}
return 0;
}