Jump to content

Operator <<

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
9 replies to this topic

#1
atod

atod

    Newbie

  • Members
  • PipPip
  • 13 posts
I have a class called "Product" and i want to use the operator << to customize the output.

int main()

{

Product p1;

cout <<  p1;

}

I want "cout << p1" to show some variables of p1.


My question is how do i write the prototype and method?

This is what i've got so far...
Prototype (in file "product.h"):

friend class ostream& operator<<(ostream& os, Product& other);

Method (in file "product.cpp"):

ostream& operator<<(ostream& os, Product& other)

{

return os << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription() << std::endl;

}



#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
I wouldn't include the std::endl at the end, in case you need to chain in something else on the same line. Without attempting to run it, however, that looks like it should work.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
atod

atod

    Newbie

  • Members
  • PipPip
  • 13 posts
Thanks for the tip :) but still, it does not work.

These are the two errors i get:

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Product' (or there is no acceptable conversion) ...\main.cpp

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion) ...\product.cpp


error 1 points to this "cout << p1;" (in main.cpp)

error 2 points to this line:
return os << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription() << std::endl;
(in product.cpp)

#4
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
I'm probably going to need to see more code before I can tell what's happening.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#5
atod

atod

    Newbie

  • Members
  • PipPip
  • 13 posts
Okej! :)

Product.h
#ifndef PRODUCT_H

#define PRODUCT_H


#include <string>

#include <iostream>

#include <iosfwd>


class Product

{

	friend class ostream& operator<<(ostream& lol, Product& other);


public:

	Product();

	Product(std::string name);

	Product(std::string name, double price);

	Product(std::string name, double price, std::string comment);

	Product(Product &other);

	~Product();

	

	static int getNumberOfProducts();

	void virtual setPrice(double price);

	double virtual getPrice();

	void setDescription(std::string comment);

	std::string getName();

	std::string getDescription();

	Product operator = (const Product &other);

	

protected:

	double _price;


private:

	std::string _name;

	std::string _comment;

	static int _count;


};


#endif //PRODUCT_H

Product.cpp
#include <string>

#include <iostream>

#include "Product.h"


int Product::_count(0);


	Product::Product()

	{

	}


	Product::Product(std::string name, double price)

	{

		_name = name;

		_price = price;

		_count++;

	}

	Product::Product(std::string name)

	{

		_name = name;

		_price = 0;

		_count++;

	}

	Product::Product(std::string name, double price, std::string comment)

	{

		_name = name;

		_price = price;

		_comment = comment;

		_count++;

	}

	Product::Product(Product &other)// Så här används COPY konstruktorn t.ex.: Product pineapple = Product( "Ananas" );

	{

		_name = other._name;

		_price = other._price;

		_comment = other._comment;

		other._count++;

	}

	Product::~Product()

	{

		_count--;

	}

	

	//ostream& Product::operator <<(Product &other)

	ostream& operator<<(ostream& lol, Product& other)

	{

		return lol << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription();

	}

		


	int Product::getNumberOfProducts()

	{

		return _count;

	}


	void Product::setPrice(double price)

	{

		_price = price;

	}


	void Product::setDescription(std::string comment)

	{

		_comment = comment;

	}


	std::string Product::getName()

	{

		return _name;

	}


	double Product::getPrice()

	{

		return _price;

	}


	std::string Product::getDescription()

	{

		return _comment;

	}


	Product Product::operator =(const Product &other)

	{

		std::cout << "inne i PRODUCTS operator =" << std::endl;


		_name = other._name;

		_price = other._price;

		_comment = other._comment;


		return *this;

	}




main.cpp
#include <iostream>

#include <vector>

#include "Product.h"

#include "Lager.h"


using namespace std;


// Visar upp en produkt

void displayProduct( Product& product );


// Visar upp en vektor med produkter

void displayProducts( vector<Product*> products );


// Visar reklam för en billig vara

void advertiseCheap( Product product );


int main()

{

	// Labb 3 Uppgift 1 test start...

	Lager lMilk("milk", 10, 2);

	cout << "Name: " << lMilk.getName() << endl;

	cout << "Price: " << lMilk.getPrice() << endl;

	cout << "Kilos: " << lMilk.getKg() << endl;

	cout << "Price/Kilo: " << lMilk.getPriceKg() << endl;

	lMilk.addKgToProduct(1);

	cout << "Add 1 Kilo" << endl;

	cout << "Price/Kilo: " << lMilk.getPriceKg() << endl;

	lMilk.delKgToProduct(1);

	cout << "Delete 1 Kilo" << endl;

	cout << "Price/Kilo: " << lMilk.getPriceKg() << endl;

	cout << "Get price: " << lMilk.getPrice() << endl;

	lMilk.setPrice(20);

	cout << "Set price to 20: " << lMilk.getPrice() << endl;

	cout << "Price/Kilo: " << lMilk.getPriceKg() << endl;

	cout << "Get price of 5 kilos: " << lMilk.getPriceKg(5) << endl;

	// ...test end Labb 3 Uppgift 1

	cout << endl << "======VG=====" << endl;

	// Labb 3 uppgift 1 VG test start...

	Product p1("P ETT"), p2("P TVA", 10);

	cout << "p1 name: " << p1.getName() << endl;

	cout << "p2 name: " << p2.getName() << endl;

	cout << "p2 price: " << p2.getPrice() << endl;

	p2.setDescription("comment created on p2");

	p1 = p2;

	cout << "p1 name: " << p1.getName() << endl;

	cout << "p1 comment: " << p1.getDescription() << endl;

	cout << p1;

	Product p3 = p1;

	cout << "p3 name: " << p3.getName() << endl;

	

	cout << endl << endl << endl;

	// ... test end Labb 3 uppgift 1 VG


    // Skapar några basvaror som vi alltid vill ha

    Product pineapple = Product( "Ananas" );

    Product milk = Product( "Mjölk", 7 );

    Product mustard = Product( "Gotlandssenap", 35, "Mycket exklusiv och god" );

	

    // Visar produkterna

    displayProduct( pineapple );

    displayProduct( milk );

    displayProduct( mustard );


    // Nu borde det finnas 3 produkter

    cout << "Just nu finns de " << Product::getNumberOfProducts() << " produkter i sortimentet." << endl << endl;


    // Fyller vårt sortiment med teer vi vill ha

    string teaName[] = {"Guteblandning", "Kalkstensdrömmar", "Munkte", "Gotländsk sommarblandning", "Sylves lilla gröna", "Den Raude"};

    vector<Product*> teas;

    for( int i = 0; i < sizeof(teaName)/sizeof(string); i++ )

    {

        Product* tea = new Product( teaName[i], 22, "Gotländskt te" );

        teas.push_back( tea );

    }


    // Visar våra tesorter

    displayProducts( teas );

    // Nu borde det finnas 9 produkter

    cout << "Just nu finns de " << Product::getNumberOfProducts() << " produkter i sortimentet." << endl << endl ;


    // Grannbutiken sålde visst också te, vi tar bort det ur sortimentet igen

    cout << "Grannbutiken sålde visst också te, vi tar bort det ur sortimentet igen" << endl;

    for( vector<Product*>::iterator tea = teas.begin(); tea != teas.end(); tea++ )

    {

        delete *tea;

    }

    // Nu borde det finnas 3 produkter

    cout << "Just nu finns de " << Product::getNumberOfProducts() << " produkter i sortimentet." << endl << endl;


    // Vi har kommit över ett parti billig annanas

    pineapple.setPrice( 15 );

    pineapple.setDescription( "Mycket god och taggig! Måste provas" );

    advertiseCheap( pineapple );


    // Nu borde det finnas 3 produkter. KONTROLLERA EXTRA NOGA!

    cout << "Just nu finns de " << Product::getNumberOfProducts() << " produkter i sortimentet." << endl << endl;

}


void displayProduct( Product& product )

{

    cout << product.getName() << " kostar " << product.getPrice() << " kr: " << product.getDescription() << endl;

}


void displayProducts( vector<Product*> products )

{

    for( vector<Product*>::iterator product = products.begin(); product != products.end(); product++ )

    {

        displayProduct( **product );

    }

}


void advertiseCheap( Product product )

{

    cout << "EXTRA! EXTRA!" << endl;

    cout << product.getName() << ": " << product.getDescription() << endl

         << "Till det låga priset av " << product.getPrice() << " kr" << endl

         << "Köp idag!" << endl;

}


I have no clue where the problem could be, as you said it looks like it should work as of what i understand from several google searches as well.

There is another class called "Lager" but it's not included, the problem should be somewhere in these 3.

Really appreciate the help! And so quickly :)

#6
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
I believe that in Product.h this:
	friend class ostream& operator<<(ostream& lol, Product& other);
needs to be this:
	friend class std::ostream& operator<<(std::ostream& lol, Product& other);

also in Product.cpp this:
	ostream& operator<<(ostream& lol, Product& other)
	{
		return lol << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription();
	}
needs to be this:
	std::ostream& operator<<(std::ostream& lol, Product& other)
	{
		return lol << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription();
	}

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#7
atod

atod

    Newbie

  • Members
  • PipPip
  • 13 posts
Nope that wasent it.

I got this error times two:

error C2242: typedef name cannot follow class/struct/union ...\product.h


I also tried no std:: on the first ostream like this
Code:
friend class ostream& operator<<(std::ostream& lol, Product& other);

And this
Code:
ostream& operator<<(std::ostream& lol, Product& other)

{

return lol << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription();

}

But then i got these two errors:

error C2027: use of undefined type 'ostream' ...\main.cpp

error C2440: 'return' : cannot convert from 'std::basic_ostream<_Elem,_Traits>' to 'ostream &' ...\product.cpp


It really seems impossible :p

#8
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
Here's what got me closer (I'm still missing a file, so can't fully compile):
Product.h
#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
#include <iostream>
#include <iosfwd>

class Product
{
  friend std::ostream& operator<<(std::ostream& lol, Product& other);

  public:
  Product();
  Product(std::string name);
  Product(std::string name, double price);
  Product(std::string name, double price, std::string comment);
  Product(Product &other);
  ~Product();
  
  static int getNumberOfProducts();
  void virtual setPrice(double price);
  double virtual getPrice();
  void setDescription(std::string comment);
  std::string getName();
  std::string getDescription();
  Product operator = (const Product &other);
  
  protected:
  double _price;

  private:
  std::string _name;
  std::string _comment;
  static int _count;

};

#endif //PRODUCT_H
Product.cpp
#include <string>
#include <iostream>
#include "Product.h"

int Product::_count(0);

  Product::Product()
{
}

  Product::Product(std::string name, double price)
{
  _name = name;
  _price = price;
  _count++;
}
  Product::Product(std::string name)
{
  _name = name;
  _price = 0;
  _count++;
}
  Product::Product(std::string name, double price, std::string comment)
{
  _name = name;
  _price = price;
  _comment = comment;
  _count++;
}
  Product::Product(Product &other)// Så här används COPY konstruktorn t.ex.: Product pineapple = Product( "Ananas" );
{
  _name = other._name;
  _price = other._price;
  _comment = other._comment;
  other._count++;
}
  Product::~Product()
{
  _count--;
}
  
  //ostream& Product::operator <<(Product &other)
  std::ostream& operator<<(std::ostream & lol, Product& other)
{
  lol << other.getName() << " kostar " << other.getPrice() << " kr: " << other.getDescription();
  return lol;
}
    

  int Product::getNumberOfProducts()
{
  return _count;
}

  void Product::setPrice(double price)
{
  _price = price;
}

  void Product::setDescription(std::string comment)
{
  _comment = comment;
}

  std::string Product::getName()
{
  return _name;
}

  double Product::getPrice()
{
  return _price;
}

  std::string Product::getDescription()
{
  return _comment;
}

  Product Product::operator =(const Product &other)
{
  std::cout << "inne i PRODUCTS operator =" << std::endl;

  _name = other._name;
  _price = other._price;
  _comment = other._comment;

  return *this;
}

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#9
atod

atod

    Newbie

  • Members
  • PipPip
  • 13 posts
Yes it worked!

I feel kind of stupid now since the error i pasted:
error C2242: typedef name cannot follow class/struct/union

Kind of yelled REMOVE "CLASS" in front of std:: ostream.

Thanks for the help!

#10
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
No problem. There were a couple other issues as well. I find that MinGW has slightly clearer error messages, but you can only really deal with one message at a time, as it tends to cascade messily after the first.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog