I need to overload the << and >> operators, but I don't see any errors.
When i overloaded only operator << and initialize the object in main directly.
I don't receive any error. But when i overloaded operator >>, I don't see any pop up to enter the variables for the object.
Here is the code and I don't seem to find what's wrong with it
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
class vehicle
{
protected:
int number, year, cost;
char *make, *model, *bodyStyle, *color;
public:
vehicle(int = 0, int = 0, char* = NULL, char* = NULL, char* = NULL, char* = NULL, int = 0);
~vehicle();
friend istream &operator>>(istream& stream, vehicle& v);
friend ostream &operator<<(ostream& stream, const vehicle& v);
};
vehicle::vehicle(int a, int b, char* ma1, char* mod1, char* bs1, char* c1, int cos)
{
number = a;
year = b;
make = new char[strlen(ma1) + 1];
assert(make);
strcpy (make,ma1);
model = new char[strlen(mod1) + 1];
assert(model);
strcpy(model,mod1);
bodyStyle = new char[strlen(bs1) + 1];
assert(bodyStyle);
strcpy(bodyStyle,bs1);
color = new char[strlen(c1) + 1];
assert(color);
strcpy(color,c1);
cost = cos ;
}
vehicle::~vehicle()
{
delete[] make;
delete[] model;
delete[] bodyStyle;
delete[] color;
}
istream& operator>>(istream& stream, vehicle& v)
{
stream>>v.number;
stream>>v.year;
stream>>v.cost;
stream>>v.make;
stream>>v.model;
stream>>v.bodyStyle;
stream>>v.color;
return stream;
}
ostream& operator<<(ostream& stream, const vehicle& v)
{
stream<<v.number<<endl;
stream<<v.year<<endl;
stream<<v.cost<<endl;
stream<<v.make<<endl;
stream<<v.model<<endl;
stream<<v.bodyStyle<<endl;
stream<<v.color<<endl;
return stream;
}
class Truckvehicle : public vehicle
{
int passengers, mileage, grossWeight, tempGross;
char *poweredBy;
public:
Truckvehicle(int = 0, int = 0, char* = NULL, char* = NULL, char* = NULL, char* = NULL, int = 0, int = 0, int = 0, int = 0, char * = NULL, int = 0);
~Truckvehicle();
friend ostream & operator<<(ostream& stream, const Truckvehicle& tv);
friend istream & operator>>(istream& stream, Truckvehicle& tv);
};
Truckvehicle::Truckvehicle(int a, int b, char* ma1, char* mod1, char* bs1, char* c1, int cos, int pass1, int mil, int gross, char* pb, int tg) :
vehicle(a, b, ma1, mod1, bs1, c1, cos), passengers(pass1), mileage(mil), grossWeight(gross), poweredBy(pb), tempGross(tg)
{
passengers = pass1;
mileage = mil;
grossWeight = gross;
poweredBy = new char[strlen(pb) + 1];
assert(poweredBy);
strcpy(poweredBy, pb);
tempGross = tg;
}
Truckvehicle :: ~Truckvehicle()
{
delete[] poweredBy;
}
istream& operator>>(istream& stream, Truckvehicle& tv)
{
stream>>tv.number;
stream>>tv.year;
stream>>tv.make;
stream>>tv.model;
stream>>tv.bodyStyle;
stream>>tv.color;
stream>>tv.cost;
stream>>tv.passengers;
stream>>tv.mileage;
stream>>tv.grossWeight;
stream>>tv.poweredBy;
stream>>tv.tempGross;
return stream;
}
ostream & operator<<(ostream& stream, const Truckvehicle& tv)
{
stream<<tv.number<<endl;
stream<<tv.year<<endl;
stream<<tv.make<<endl;
stream<<tv.model<<endl;
stream<<tv.bodyStyle<<endl;
stream<<tv.color<<endl;
stream<<tv.cost<<endl;
stream<<tv.passengers<<endl;
stream<<tv.mileage<<endl;
stream<<tv.grossWeight<<endl;
stream<<tv.poweredBy<<endl;
stream<<tv.tempGross<<endl;
return stream;
}
int main()
{
Truckvehicle TV;
//Read in the following values for TV (111111, 2014,"Toyota","Tacoma", "4X4", "Black",25000, 2, 15000,333333,"Gas", 222222);
cin>>TV;
cout<<TV;
return 0;
}
Hi there you might want to study this code, which compiles without errors and warnings in Wandbox using GCC HEAD 8 compiler. I will answer any questions about my code in a timely fashion.
Regards, Micha
#include <iostream>
// Don't use <blah.h>, prefer using <cblah>.
#include <cstring>
#include <cassert>
// extra includes.
#include <string>
#include <sstream>
using namespace std;
class vehicle
{
friend ostream& operator<< (ostream& stream, vehicle const& v);
friend istream& operator>> (istream& stream, vehicle& v);
protected:
int number, year, cost;
char *make, *model, *bodyStyle, *color;
public:
vehicle(int = 0,
int = 0,
char const* = "-", // Don't choose NULL here - prevents segmentation fault in main!
char const* = "-",
char const* = "-",
char const* = "-",
int = 0);
~vehicle();
};
vehicle::vehicle(int a,
int b,
char const* ma1,
char const* mod1,
char const* bs1,
char const* c1,
int cos)
{
number = a;
year = b;
make = new char[strlen(ma1) + 1];
assert(make);
strcpy(make, ma1);
model = new char[strlen(mod1) + 1];
assert(model);
strcpy(model, mod1);
bodyStyle = new char[strlen(bs1) + 1];
assert(bodyStyle);
strcpy(bodyStyle, bs1);
color = new char[strlen(c1) + 1];
assert(color);
strcpy(color, c1);
cost = cos;
}
vehicle::~vehicle()
{
if (make) delete[] make;
if (model) delete[] model;
if (bodyStyle) delete[] bodyStyle;
if (color) delete[] color;
}
ostream& operator<< (ostream& stream, vehicle const& v)
{
stream << v.number << endl;
stream << v.year << endl;
stream << v.cost << endl;
stream << v.make << endl;
stream << v.model << endl;
stream << v.bodyStyle << endl;
stream << v.color << endl;
return stream;
}
istream& operator>> (istream& stream, vehicle& v)
{
stream >> v.number;
stream >> v.year;
stream >> v.cost;
stream >> v.make;
stream >> v.model;
stream >> v.bodyStyle;
stream >> v.color;
return stream;
}
class Truckvehicle : public vehicle
{
friend ostream& operator<< (ostream& stream, Truckvehicle const& tv);
friend istream& operator>> (istream& stream, Truckvehicle& tv);
int passengers, mileage, grossWeight, tempGross;
char *poweredBy;
public:
Truckvehicle(int = 0,
int = 0,
char const* = "-",
char const* = "-",
char const* = "-",
char const* = "-",
int = 0,
int = 0,
int = 0,
int = 0,
char const* = "-",
int = 0);
~Truckvehicle();
};
Truckvehicle::Truckvehicle(int a,
int b,
char const* ma1,
char const* mod1,
char const* bs1,
char const* c1,
int cos,
int pass1,
int mil,
int gross,
char const* pb,
int tg)
:
vehicle(a, b, ma1, mod1, bs1, c1, cos)
{
passengers = pass1;
mileage = mil;
grossWeight = gross;
poweredBy = new char[strlen(pb) + 1];
assert(poweredBy);
strcpy(poweredBy, pb);
tempGross = tg;
}
Truckvehicle::~Truckvehicle()
{
delete[] poweredBy;
}
ostream& operator<< (ostream& stream, Truckvehicle const& tv)
{
// vehicle part.
stream <<tv.number <<endl;
stream <<tv.year <<endl;
stream <<tv.make <<endl;
stream <<tv.model <<endl;
stream <<tv.bodyStyle <<endl;
stream <<tv.color <<endl;
stream <<tv.cost <<endl;
// extra truck part.
stream <<tv.passengers <<endl;
stream <<tv.mileage <<endl;
stream <<tv.grossWeight <<endl;
stream <<tv.poweredBy <<endl;
stream <<tv.tempGross <<endl;
return stream;
}
istream& operator>> (istream& stream, Truckvehicle& tv)
{
// vehicle part.
stream >>tv.number;
stream >>tv.year;
stream >>tv.make;
stream >>tv.model;
stream >>tv.bodyStyle;
stream >>tv.color;
stream >>tv.cost;
// extra truck part.
stream >>tv.passengers;
stream >>tv.mileage;
stream >>tv.grossWeight;
stream >>tv.poweredBy;
stream >>tv.tempGross;
return stream;
}
// Simulates usage of std::operator>> ().
void initializeTruckvehicle(Truckvehicle& TV,
int a,
int b,
char const* ma1,
char const* mod1,
char const* bs1,
char const* c1,
int cos,
int pass1,
int mil,
int gross,
char const* pb,
int tg)
{
string s;
s += static_cast <ostringstream *> (&( ostringstream() << a )) -> str();
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << b )) -> str();
s += " ";
s += ma1;
s += " ";
s += mod1;
s += " ";
s += bs1;
s += " ";
s += c1;
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << cos )) -> str();
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << pass1 )) -> str();
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << mil )) -> str();
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << gross )) -> str();
s += " ";
s += pb;
s += " ";
s += static_cast <ostringstream *> (&( ostringstream() << tg )) -> str();
s += " ";
istringstream in(s);
in >> TV;
}
int main()
{
cout << "Truck 1>" << endl;
Truckvehicle TV1 (111111,
2014,
"Toyota",
"Tacoma",
"4X4",
"Black",
25000,
2,
15000,
333333,
"Gas",
222222);
cout << TV1;
cout << "Truck 2>" << endl;
Truckvehicle TV2;
cout << TV2;
cout << "Truck 3>" << endl;
Truckvehicle TV3;
initializeTruckvehicle (TV3,
111111,
2014,
"Toyota",
"Tacoma",
"4X4",
"Black",
25000,
2,
15000,
333333,
"Gas",
222222);
cout << TV3;
}
Related
I have a template class Polinom, that uses generic data types(int, float, double, class Complex(defined by me)), and I want to convert a string to Polinom using this function for reading and a constructor:
Polion.cpp
template<typename T>
istream& operator>>(istream& in, Polinom<T>& P) {
char line[1000];
in.getline(line, 1000);
int gr = -1;
T cf[100];
char* pt;
pt = strtok(linie, " ");
while (pt) {
cf[++gr] = T(pt);
pt = strtok(NULL, " ");
}
P = Polinom<T>(gr, cf);
return in;
}
Complex.cpp
Complex::Complex(const char* str){
/*
...
*/
}
Everything is fine when I use Complex data type
(
Polinom a(12, 4);
std::cout << a << endl;) // I defined a friend ostream function for this line;
)
because I write this constructor Complex::Complex(const char* str)
The problems appears when I use primitive data types
Polinom<int> a(12, 4); because of T(const char* ) ===> int(const char*)
How can I solve this?
Thank you very much!
This looks like you're reinventing the wheel. There's already a proper operator>> for int. You should add an overload for your Complex, so that in >> cf[gr++] compiles for every T.
I updated my code like this:
Polinom.cpp
template<typename T>
istream& operator>>(istream& in, Polinom<T>& P) {
char linie[1000];
in.getline(linie, 1000);
int gr = -1;
T cf[100];
char* pt;
pt = strtok(linie, " ");
while (pt) {
T a;
string aux;
try {
aux = string(pt);
if(aux.find("i") != string::npos) throw std::invalid_argument("invalid");
a = std::stod(pt);
}
catch(const std::invalid_argument& e){
cf[++gr] = (T)(pt);
goto execute;
}
cf[++gr] = a;
execute:
pt = strtok(NULL, " ");
}
P = Polinom<T>(gr, cf);
return in;
}
int main()
{
Polinom<Complex> a(12, 4); // it works
std::cout << a << endl;
Polinom<int> b; // it works
std::cin >> b;
std::cout << b;
Polinom<double> c; // error C2440 'type cast': cannot convert from char*
// to 'T'
std::cin >> c;
std::cout << c;
return 0;
}
I am working on my school project that has a base class and a derived class with some other classes.
Product.h
#ifndef AMA_PRODUCT_H
#define AMA_PRODUCT_H
#include <iostream>
#include <fstream>
namespace AMA
{
const int max_sku_length = 7;
const int max_unit_length = 10;
const int max_name_length = 75;
const double TRate = 0.13;
class Product
{
private:
char m_type;
char m_sku[max_sku_length +1];
char m_unit[max_unit_length + 1];
char* m_name;
int m_Cquantity;
int m_Nquantity;
double m_price;
bool m_status;
protected:
void sku(const char* setSku) { strncpy(m_sku, setSku, max_sku_length); }
const char* name() const { return m_name; }
bool taxed() const { return m_status; }
const char* sku() const { return m_sku;}
void name(const char*);
const char* unit() const;
double price() const;
void message(const char*);
bool isClear() const;
public:
double cost() const;
bool operator==(const char* src) { return strcmp(m_sku, src) == 0; }
bool isEmpty() const { return ((m_sku[0] == '\0') && (m_name == nullptr) && (m_price == 0) && (m_Cquantity == 0)); }
int qtyNeeded() const { return m_Nquantity; }
int quantity() const { return m_Cquantity; }
int operator+=(int src) { return m_Cquantity += src; }
Product();
Product(const char* sku, const char* name, const char* unit, int qty = 0,
bool taxed = true, double price = 0.0, int qtyNeeded = 0);
Product(const Product&);
Product& operator=(const Product&);
~Product();
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
double total_cost() const;
void quantity(int);
bool operator>(const char*) const;
bool operator>(const Product&) const;
};
std::ostream& operator<<(std::ostream&, const Product&);
std::istream& operator>>(std::istream&, Product&);
double operator+=(double&, const Product&);
}
#endif
MyProduct.h
#ifndef AMA_MY_PRODUCT_H
#define AMA_MY_PRODUCT_H
#include <fstream>
#include "Product.h"
#include "ErrorState.h"
namespace AMA {
class MyProduct : public Product {
public:
MyProduct();
MyProduct(const char* sku, const char* name, const char* unit, int qty = 0,
bool isTaxed = true, double price = 0.0, int qtyNeeded = 0);
const char* sku() const;
const char* name() const;
const char* unit() const;
bool taxed() const;
double price() const;
double cost() const;
};
class Test {
MyProduct product; // Error
const char* filename;
public:
Test(const char* file);
Test(const char* file, const char* theSku, const char* theName);
std::fstream& store(std::fstream& file, bool addNewLine = true) const;
std::fstream& load(std::fstream& file);
std::ostream& write(std::ostream& os, bool linear) const;
std::istream& read(std::istream& is);
int operator+=(int value);
bool operator==(const char* sku) const;
friend std::ostream& operator<<(std::ostream& os, const Test& test);
friend double operator+=(double& d, const Test& test);
friend std::istream& operator>>(std::istream& is, Test& test);
};
}
#endif
MyProduct.cpp
#include <iomanip>
#include <fstream>
#include <cstring>
#include "MyProduct.h"
#ifdef TAB
#undef TAB
#endif
#define TAB '\t'
using namespace std;
namespace AMA {
MyProduct::MyProduct() : Product("", "", "") {}
MyProduct::MyProduct(const char* sku, const char* name, const char* unit, int qty,
bool isTaxed, double price, int qtyNeeded) :
Product(sku, name, unit, qty, isTaxed, price, qtyNeeded) {}
const char* MyProduct::sku() const { return Product::sku(); }
const char* MyProduct::name() const { return Product::name(); }
const char* MyProduct::unit() const { return Product::unit(); }
bool MyProduct::taxed() const { return Product::taxed(); }
double MyProduct::price() const { return Product::price(); }
double MyProduct::cost() const { return Product::cost(); }
Test::Test(const char* file) : filename(file) { }
Test::Test(const char* file, const char* theSku, const char* theName) :
product(theSku, theName, ""), filename(file) { }
std::fstream& Test::store(std::fstream& file, bool addNewLine) const {
if (!product.isEmpty()) {
file.open(filename, ios::out | ios::app);
file << product.sku() << TAB << product.name() << TAB << product.unit() << TAB <<
(product.taxed() ? 1 : 0) << TAB << product.price() << TAB << product.quantity() << TAB <<
product.qtyNeeded() << endl;
file.clear();
file.close();
}
return file;
}
std::fstream& Test::load(std::fstream& file) {
char sku_[max_sku_length + 1];
char name[max_name_length + 1];
char unit[max_unit_length + 1];
int quantity, qtyNeeded;
double price_;
char taxed_;
file.open(filename, ios::in);
file >> sku_;
file >> name;
file >> unit;
file >> taxed_;
file >> price_;
file >> quantity;
file >> qtyNeeded;
file.clear();
file.close();
product = MyProduct(sku_, name, unit, quantity, taxed_ != 0, price_, qtyNeeded); //ERROR
return file;
}
std::ostream& Test::write(std::ostream& os, bool linear) const {
return product.isEmpty() ? os : (os << product.sku() << ": " << product.name() << ", quantity: "
<< product.quantity() << ", quantity needed:" << product.qtyNeeded()
<< ", Cost: " << fixed << setprecision(2) << product.cost());
}
std::istream& Test::read(std::istream& is) {
char sku_[max_sku_length + 1];
char name[max_name_length + 1];
char unit[max_unit_length + 1];
int quantity, qtyNeeded;
double price_;
char taxed_;
cout << " Sku: ";
is >> sku_;
cout << " Name (no spaces): ";
is >> name;
cout << " Unit: ";
is >> unit;
cout << " Taxed? (y/n): ";
is >> taxed_;
cout << " Price: ";
is >> price_;
cout << " Quantity On hand: ";
is >> quantity;
cout << " Quantity Needed: ";
is >> qtyNeeded;
product = MyProduct(sku_, name, unit, quantity, taxed_ != 0, price_, qtyNeeded); //ERROR
return is;
}
int Test::operator+=(int value) {
product.quantity(product += value);
return product.quantity();
}
bool Test::operator==(const char* sku) const {
return !std::strcmp(product.sku(), sku);
}
std::ostream& operator<<(std::ostream& os, const Test& test) {
return test.product.write(os, true);
}
double operator+=(double& d, const Test& test) {
return d += test.product.total_cost();
}
std::istream& operator>>(std::istream& is, Test& test) {
return test.product.read(is);
}
}
I am getting errors that I don't really know how to fix
object of abstract class type "AMA::MyProduct" is not allowed
'AMA::MyProduct': cannot instantiate abstract class
a cast to abstract class "AMA::MyProduct" is not allowed
Can someone help me out please?
The errors are self explanatory.
AMA::MyProduct is an abstract class, and such it cannot be instantiated directly.
A class is abstract when it has at least 1 abstract method (virtual and = 0 keywords on it). An abstract method MUST be overridden in a derived class, and you MUST instantiate that derived class, not the abstract class.
AMA::MyProduct is abstract because it does not override the 4 abstract methods it inherits from AMA::Product:
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
You implemented them in AMA::Test instead of in AMA::MyProduct.
For a project I'm doing we have to populate a queue with "House" objects. The "House" objects get their information from a file called "data.dat". Each line of the file is another thing that goes into the house object. So first I take a char* for the address, then an int, another int, a third int, and then another char*. We aren't aloud to use strings to get the char* variables which I believe is where I'm running into my problem. Every time I compile it tells me I have a segmentation fault. Here is the area of my queue.cpp that I'm pretty sure the error is in
#include"queue.h"
#include<iostream>
#include<fstream>
#include<istream>
Queue::Queue(const char *filename){
head = NULL;
tail = NULL;
std::ifstream infile(filename);
char * address = NULL;
int footage = 0;
int bedrooms = 0;
int bathrooms = 0;
char * features = NULL;
while(!infile.eof()){
while(infile.get() != '\n'){
//std::cout << infile.get();
infile.get(address[i]);
}
infile >> footage >> bedrooms >> bathrooms;
while(infile.get() != '\n'){
infile.get(features[i]);
}
enqueue(House(address, footage, bedrooms, bathrooms, features));
}
infile.close();
}
Here is the house object header file:
House();
House(char * ad, int fo, int be, int ba, char * fe);
char * getAddress();
int getFootage();
int getBedrooms();
int getBathrooms();
char * getFeatures();
void setAddress(char * ad);
void setFootage(int fo);
void setBedrooms(int be);
void setBathrooms(int ba);
void setFeatures(char * fe);
friend std::ostream& operator<<(std::ostream& out, House& house);
private:
char * address;
int footage;
int bedrooms;
int bathrooms;
char * features;
};
You need to initialize the features and address first, either by using new or by creating it as array of chars of some length.
The way you do it you're trying to write to the memory that was't assigned yet - hence buffer overflow.
For fun, here's a cleaned up version
mainly it replaces char* with std::string (since we're doing C++)
it makes the whole thing self-contained.
It uses correct input validation (don't use while (!infile.eof()), check extraction operators)
I didn't implement your Queue :)
Live On Coliru
#include <iostream>
#include <fstream>
#include <sstream>
struct House {
House()
: address(), footage(0), bedrooms(0), bathrooms(0), features()
{ }
House(std::string ad, int fo, int be, int ba, std::string fe)
: address(ad), footage(fo), bedrooms(be), bathrooms(ba), features(fe)
{ }
std::string getAddress() const { return address; }
int getFootage() const { return footage; }
int getBedrooms() const { return bedrooms; }
int getBathrooms() const { return bathrooms; }
std::string getFeatures() const { return features; }
void setAddress(std::string ad) { address = ad; }
void setFootage(int fo) { footage = fo; }
void setBedrooms(int be) { bedrooms = be; }
void setBathrooms(int ba) { bathrooms = ba; }
void setFeatures(std::string fe) { features = fe; }
friend std::ostream &operator<<(std::ostream &out, House const &house) {
return out << "Address: " << house.getAddress() << '\n'
<< "Footage: " << house.getFootage() << '\n'
<< "Bed rooms: " << house.getBedrooms() << '\n'
<< "Bath rooms: " << house.getBathrooms() << '\n'
<< "Features: " << house.getFeatures() << '\n';
}
private:
std::string address;
int footage;
int bedrooms;
int bathrooms;
std::string features;
};
struct Queue {
Queue(std::string filename);
struct Node {
House value;
Node* next;
};
Node *head, *tail;
void enqueue(House const& h) {
// TODO
std::cout << h << "\n";
}
};
Queue::Queue(std::string filename) : head(nullptr), tail(nullptr) {
std::ifstream infile(filename);
std::string address;
int footage = 0;
int bedrooms = 0;
int bathrooms = 0;
std::string features;
std::string line; // lines
while (getline(infile, address) && getline(infile, line)) {
std::istringstream iss(line);
if (iss >> footage >> bedrooms >> bathrooms && getline(iss, features)) {
enqueue(House(address, footage, bedrooms, bathrooms, features));
}
}
}
int main()
{
Queue q("data.dat");
}
For input:
Blv. Dreams Abroken 24, 78377d XG, ClassyCode
2 4 1 pool sauna porch indoor-parking
Oyi. Qernzf Noebxra 24, 78377q KT, PynfflPbqr
3 8 2 cbby fnhan cbepu vaqbbe-cnexvat
It prints the output:
Address: Blv. Dreams Abroken 24, 78377d XG, ClassyCode
Footage: 2
Bed rooms: 4
Bath rooms: 1
Features: pool sauna porch indoor-parking
Address: Oyi. Qernzf Noebxra 24, 78377q KT, PynfflPbqr
Footage: 3
Bed rooms: 8
Bath rooms: 2
Features: cbby fnhan cbepu vaqbbe-cnexvat
I want to write a print function for a class AutoData that has information about cars in it. With this print function, I would ideally like to print out a vector that contains many different class objects. I have already written get functions for each element of the objects, but I am still a bit unsure of how to go about using those to write a function to print out the data in the following format:
mpg:cylinders:displacement:horsepower:weight:acceleration:modelYear:origin:carName
For example:
10.0:8:360.0:215.0:4615.:14.0:70:1:ford f250
10.0:8:307.0:200.0:4376.:15.0:70:1:chevy c20
11.0:8:318.0:210.0:4382.:13.5:70:1:dodge d200
The class is:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class AutoData {
public:
AutoData()
{
mpg = 0;
cylinders = 0;
displacement = 0;
horsepower = 0;
weight = 0;
acceleration = 0;
modelYear = 0;
origin = 0;
carName = "";
}
AutoData( const AutoData & rhs)
{
setAuto(rhs.mpg, rhs.cylinders, rhs.displacement, rhs.horsepower, rhs.weight, rhs.acceleration, rhs.modelYear, rhs.origin, rhs.carName);
}
void setAuto(float mp, int cy, float di, float ho, float we, float ac, int mo, int o, string ca)
{
mpg = mp;
cylinders = cy;
displacement = di;
horsepower = ho;
weight = we;
acceleration = ac;
modelYear = mo;
origin = o;
carName = ca;
}
const float & getmpg( ) const
{
return mpg;
}
const int & getcylinders( ) const
{
return cylinders;
}
const float & getdisplacement( ) const
{
return displacement;
}
const float & gethorsepower( ) const
{
return horsepower;
}
const float & getweight( ) const
{
return weight;
}
const float & getacceleration( ) const
{
return acceleration;
}
const int & getmodelYear( ) const
{
return modelYear;
}
const int & getorigin( ) const
{
return origin;
}
const string & getcarName( ) const
{
return carName;
}
bool operator == (const AutoData & rhs ) const
{
if( getmpg( ) == rhs.getmpg( ) )
{
return gethorsepower( ) == rhs.gethorsepower( );
}
else
{
return false;
}
}
bool operator > ( const AutoData & rhs ) const
{
if( rhs.getmpg( ) > getmpg( ) )
{
return true;
}
else if( getmpg( ) == rhs.getmpg( ) )
{
if( rhs.gethorsepower( ) > gethorsepower( ) )
{
return true;
}
}
else
{
return false;
}
}
private:
float mpg;
int cylinders;
float displacement;
float horsepower;
float weight;
float acceleration;
int modelYear;
int origin;
string carName;
};
Any help/advice anyone can provide would be very much appreciated!! Thanks
If you want to be able to do std::cout << AutoData();, you need to overload the output stream operator operator<<:
std::ostream& operator<< (std::ostream &out, AutoData const& data) {
out << data.getmpg() << ':';
out << data.getcylinders() << ':';
// and so on...
return out;
}
This function is not a member function, and since you have getters for each attribute, you do not have to declare this function as friend of your class.
Then you can do:
AutoData myAuto;
std::cout << myAuto << '\n';
What have you tried so far? My approach would be overloading operator<<, like:
std::ostream& operator<<(std::ostream& out, const AutoData& dasAuto) {
return out << dasAuto.getmpg() << ':' << dasAuto.getcylinders() <<
/* insert everthing in the desired order here */
std::endl;
}
And the same thing for the "reading" function, like:
std::istream& operator>>(std::istream& in, AutoData& dasAuto) {
float mpg;
int cylinders;
float displacement;
float horsepower;
float weight;
float acceleration;
int modelYear;
int origin;
string carName;
char separator;
const char SEP = ':';
if( !(in >> mpg >> separator) || (separator != SEP) ) return in;
if( !(in >> cylinders >> separator) || (separator != SEP) ) return in;
/* rinse, repeat */
if( !std::getline(in, carName) ) return in;
dasAuto.setAuto(mpg, cylinders /*, etc etc */);
return in;
}
You can read this artical to know about friend and operator <<,
http://www.cprogramming.com/tutorial/friends.html
In the class AutoData, you should declare this function:
friend ostream& operator<< (ostream& out, const AutoData& obj);
outside the class, you should define this function like this:
ostream& operator<< (ostream& out, const AutoData& obj)
{
out<<obj.mpg<<":";
//do what you want
return out;
}
I've created simple string class with some extra functions - its mainly for learning purposes.
Now i want to overload operator + to allow me add two or more char* to my string.
this is what i want to make:
tom::string TXT;
TXT="abcde" + "1234";
cout << TXT << endl;
and output have to be:
abcde1234
i want to add more than just const char* later like:
..
int NUM=34;
TXT="abcd"+NUM+"098";
cout << TXT << endl;
and output have to be:
abcd34098
ive already done similar thing with operator <<
TXT << "abcd" << ".......";
but i need it with + operator.
another thing is (probably it will be sorted with + operator)
void testF(tom::string INP) {
cout << INP << endl;
}
int NUM=123;
testF("abcd"+NUM+"efg");
with output:
abcd123efg
if i'm trying anything still ending with error:
error: invalid operands of types
‘const char [4]’ and ‘const char [3]’
to binary ‘operator+’
here is part of the tom::string class:
namespace tom {
class string {
private:
unsigned int _length;
unsigned int _search_pos;
bool _changed;
bool _indexed;
char* _buffer;
unsigned int* _indexes;
unsigned int _indexCount;
char* _emptyChar;
unsigned int _null;
char* _retBuffer[RET_BUFFERS];
short unsigned int _retBufferIndex;
// ADD to string
void _add (const char* txt) {
_buffer=(char*) realloc(_buffer, sizeof(char)*(_length+strlen(txt)+1));
memcpy(&_buffer[_length], txt, strlen(txt));
_length=_length+strlen(txt);
_buffer[_length]=static_cast<char>(0);
_changed=true;
free(_indexes);
_changed=true;
_indexCount=0;
_indexed=false;
_indexes = (unsigned int*) malloc (sizeof(unsigned int)*2);
}
// .......
// REPLACE Whole string
string& _rvs(const char* txt) {
free(_buffer);
free(_indexes);
_changed=true;
_indexCount=0;
_indexed=false;
_indexes = (unsigned int*) malloc (sizeof(unsigned int)*2);
_length=strlen(txt);
_buffer = (char*) malloc (sizeof(char)*(_length+1));
memcpy(_buffer, txt, _length);
_buffer[_length]=static_cast<char>(0);
return (*this);
}
// .......
public:
// ----------------------------------------------
// | CONSTRUCTOR |
// ----------------------------------------------
string(const char* _init="") {
_length=0;
_indexCount=0;
_changed=false;
_indexed=false;
_buffer = (char*) malloc (sizeof(char)*(strlen(_init)+1));
memcpy(_buffer, _init, strlen(_init));
_indexes = (unsigned int*) malloc (sizeof(unsigned int)*2);
_emptyChar = (char*) malloc (sizeof(char));
_buffer[strlen(_init)]=static_cast<char>(0);
_emptyChar[0]=static_cast<char>(0);
_null=(unsigned int)-1;
_retBufferIndex=0;
for (short unsigned int ii=0; ii<RET_BUFFERS; ii++) {
_retBuffer[ii] = (char*) malloc (sizeof(char));
_retBuffer[ii][0]=static_cast<char>(0);
}
}
string(const tom::string& _init) {
string((const char*)_init.c_str());
}
// ----------------------------------------------
// | DESTRUCTOR |
// ----------------------------------------------
~string() {
free(_buffer);
free(_indexes);
free(_emptyChar);
for (short unsigned int ii=0; ii<RET_BUFFERS; ii++) {
free(_retBuffer[ii]);
}
}
// .....
string& operator = (string &ttxt) {
const char* txt=ttxt.c_str();
return (_rvs(txt));
}
string& operator = (const char* txt) {
return (_rvs(txt));
}
string& operator = (int num) {
char bf[32];
sprintf (bf, "%d", num);
const char* txt=bf;
return (_rvs(txt));
}
string& operator << (const char* txt) {
_add(txt);
return(*this);
}
string& operator << (int num) {
char bf[32];
sprintf (bf, "%d", num);
const char* txt=bf;
_add(txt);
return(*this);
}
operator const char*() {
return (const char*)_buffer;
}
// .....
}
}
You can't overload operators for pointer types only. At least one of the involved types needs to be a user-defined type.
tom::string TXT;
TXT="abcde" + "1234";
cout << TXT << endl;
"abcde" + "1234" is evaluated first - you cannot make it work like you want.
You can make e.g. this work though:
tom::string TXT;
TXT=tom::string("abcde") + 987 + "1234";
cout << TXT << endl;
That will require an operator+(int) and an operator+(char const *)
EDIT: Sample operator:
operator+ should return a new object - not modify the object it is called on.
class string {
...
friend string operator+(string const & LHS, char const * RHS) {
string s = LHS;
s._add(RHS);
return s;
}
};
Thanx to Erik! ... sorted (working)
i've added to tom::string class:
friend string operator+(string const & LHS, char const * RHS) {
string s;
s=LHS;
s._add(RHS);
return s;
}
next one throwing malloc error - i have to check it, but the first working perfect!
friend string operator+(string const & LHS, char const * RHS) {
string s=LHS;
s._add(RHS);
return s;
}
and the testing:
void test2 (tom::string ooo) {
cout << ooo << endl;
}
test2(tom::string("abcde")+"AA"+"BB");
showing:
abcdeAABB
Thanx again!