Reputation: 43
This is my code so far:
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <type_traits>
// Abstract base class given - cannot be changed
class basis{
public:
virtual ~basis() { }
virtual std::istream& load(std::istream& is) = 0; // i.e., pure virtual
virtual std::ostream& save(std::ostream& os) const = 0; // i.e., pure virtual
};
// IOStream overloaded functions given - cannot be changed
inline std::ostream& operator<<(std::ostream& os, basis const& b){
return b.save(os);
}
inline std::istream& operator>>(std::istream& is, basis& b){
return b.load(is);
}
class vector3d : public basis {
private:
double x, y, z;
public:
// Define a public default constructor that initializes the x, y, and z values to
// zero values BEFORE execution enters the constructor body
vector3d() : x{ 0 }, y{ 0 }, z{ 0 } {} // default constructor
// Define a constructor accepting 3 double values (one each for x, y, and z)
// and use those arguments to set the constructed object's x, y, and z values
// BEFORE execution enters the constructor body
vector3d(double x, double y, double z) : x{ x }, y{ y }, z{ z } {}
// Since the parent basis class is abstract, you must
// Implement the load() and save() functions in your vector3d object.
// ******************************************************************
// Prototypes are given - cannot be changed
std::istream& load(std::istream& is) override {
/* old version of this function, when vector3d was struct
char lbraket = '<', comma1 = ',', comma2 = ',', rbraket = '>';
vector3d temp;
if ((is >> lbraket >> temp.x >> comma1 >> temp.y >> comma2 >> temp.z >> rbraket)
&& lbraket == '<' && comma1 == ',' && comma2 == ',' && rbraket == '>';){
v = temp;
return is;
}
else {
is.setstate(std::ios::failbit);
}
*/
return is;
}
std::ostream& save(std::ostream& os) const override {
os << '<' << vector3d.x << ',' << vector3d.y << ',' << vector3d.z << '>';
//os << static_cast <std::underlying_type_t<vector3d>> (x, y, z);
//os << static_cast <std::underlying_type_t<vector3d>>;
return os;
}
// To perform the summing of vectors, write one more function,
// e.g., an operator +() definition. You must write it as a friend
// function to the class by first writing in your vector3d class :
friend vector3d operator+(vector3d const& a, vector3d const& b);
};
// Write a definition of this operator +() function(completely outside of your
// vector3d class).
vector3d operator+(vector3d const& a, vector3d const& b) {
vector3d s{ 0,0,0 };
s.x = a.x + b.x;
s.y = a.y + b.y;
s.z = a.z + b.z;
return s;
}
// Main given - cannot be changed
int main(){
unsigned count = 0;
vector3d sum;
for (vector3d v; std::cin >> v; ++count)
sum = sum + v;
basis& bsum = sum; // bsum uses sum polymorphically
std::cout
<< "count: " << count << '\n'
<< "sum: " << bsum << '\n'
;
}
I know the load() and save() functions must be defined in vector3d. I know they must be able to input from/output to the console vectors in the format <1.0,2.0,3.0>. Input should be read in as long as the format is correct.
I don't understand how to define the load() and save() functions, or why they are called load and save (if it even matters). I tried everything in the textbook and lecture slides. I can't even find an example of how to write input/output function like these online.
I tried adapting the code from a similar but simpler program where vector3d was a struct instead of a class, but nothing has worked so far.
Upvotes: 0
Views: 34
Reputation: 43
This worked! Thank you!
std::istream& load(std::istream& is) override {
char lbraket = '<', comma1 = ',', comma2 = ',', rbraket = '>';
vector3d temp;
if ((is >> lbraket >> temp.x >> comma1 >> temp.y >> comma2 >> temp.z >> rbraket)
&& lbraket == '<' && comma1 == ',' && comma2 == ',' && rbraket == '>'){
*this = temp;
return is;
}
else {
is.setstate(std::ios::failbit);
}
return is;
}
std::ostream& save(std::ostream& os) const override {
os << '<' << x << ',' << y << ',' << z << '>';
return os;
}
Upvotes: 0