Overloading << operator, separated implementation and decleration - c++

I'm trying to overload << operator but I get an error which is below.
rollingDice.h|14|error: ‘std::ostream& rollingDice::operator<<(std::ostream&, const rollingDice&)’ must take exactly one argument|
Here is my code. I separated implementation and decleration. I think the problem occurs due to that because I coded same as so many web pages and Deitel&Deitel show.
rollingDice.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stdlib.h>
#include "rollingDice.h"
using namespace std;
rollingDice::rollingDice(unsigned int valN)
{
n=valN;
r=new int [n];
}
int rollingDice::length()
{
return n;
}
void rollingDice::generate()
{
srand48(time(NULL));
int i=0;
for (i=0; i<n; ++i)
{
r[i]=1+(lrand48()%6);
}
}
rollingDice& rollingDice::init(unsigned int valN)
{
n=valN;
r=new int [n];
return *this;
}
ostream& operator << (ostream& output, rollingDice& rd)
{
int temp=n;
if (temp>12)
temp=12;
int i=0;
for (i=0; i<temp; ++i)
{
output << rd.r[i] << " ";
}
return output;
}
double rollingDice::getAverage()
{
generate();
double total=0;
int i=0;
for (i=0; i<n; ++i)
total+=r[i];
total=total/double(n);
return total;
}
rollingDice.h
#ifndef rollingDice_H
#define rollingDice_H
#include <string>
using namespace std;
class rollingDice
{
public:
rollingDice(unsigned int n);
void generate();
rollingDice& init(unsigned int valN);
double getAverage();
int length();
ostream& operator << (ostream& output, const rollingDice& rd);
private:
unsigned int n;
int* r;
};
#endif
rollingDiceApp.cpp
#include <iostream>
#include "rollingDice.h"
using namespace std;
int main()
{
rollingDice r(16);
cout<<r.getAverage()<<endl;
cout<<r.length()<<endl;
r.init(8).generate();
cout<<r.getAverage()<<endl;
cout<<r.length()<<endl;
}

In the class definition add keyword friend to the operator declaration
friend ostream& operator << (ostream& output, const rollingDice& rd);
Otherwise the compiler consideres the operator as a member function with the first implicit parameter that corresponds to this
Also take into account that in the operator definition it seems you have to use
int temp=rd.n;
instead of
int temp=n;

Related

C++ Template: Expected primary-expression before 'double' error

When I try to run an instance of the matrix class I'm writing, I get the following error.
main.cpp|6|error: expected primary-expression before 'double'|
I believe there's something wrong with the constructor but i can't figure what.
How can I fix my code? Below what I've written so far.
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
template<class T>
class matrix{
public:
matrix(int n, int m);
~matrix();
void fillM(T n);
void print() const;
private:
T** body_;
int lin_;
int col_;
void eraseMatrix();
};
#endif
matrix.cpp
#include "matrix.h"
#include <iostream>
template<class T>
matrix<T>::matrix(int n, int m):col_(m),lin_(n),body_(new T*[n]){
for(int i=0;i<n;i++){
body_[i] = new T[m];
}
}
template<class T>
matrix<T>::~matrix<T>(){
eraseMatrix();
}
template<class T>
void matrix<T>::eraseMatrix(){
for(int i=0;i<lin_;i++){
delete [] body_[i];
}
delete [] body_;
return;
}
template<class T>
void matrix<T>::fillM(T n){
int j;
for(int i = 0;i<lin_;i++){
for(j = 0;j<col_;j++){
body_[i][j] = n;
}
}
return;
}
template<class T>
void matrix<T>::print() const{
int j;
for(int i=0;i<lin_;i++){
for(j=0;j<col_;j++){
std::cout<<body_[i][j]<<" ";
}
std::cout<<std::endl;
}
}
main.cpp
#include <iostream>
#include "matrix.h"
using namespace std;
int main(){
matrix<double>::matrix<double> A(5,5);//error happens here
A.fillM(5.2);
A.print();
return 0;
}
}
You don't need to write matrix<double>::matrix<double> to construct an instance. Just matrix<double> A(5,5);.

Question with constructor in C++ ArrayStack

I am in the process of constructing a StackArray. I already have a "Stack.h" implemented with a constructor. I was wondering what I would do in my "StackArray.h" file to use the Stack.h file. I was thinking to use inheritance but it was giving me a error.
My code is as follows:
Array.h
#include <iostream>
#include <assert.h>
using namespace std;
#ifndef _ARRAY_H
#define _ARRAY_H
template<class T>
class Array{
private:
T *a;
int length;
public:
// constructor
Array (int len){
length = len;
a = new T[length];
for (int i = 0; i < len; i++){
a[i]=0;
}
}
// destructor
~Array()
{delete[] a;}
// operator overload
T& operator [](int i){
assert (i>=0 && i < length);
return a[i];
}
//get the length of the array
int arraylength(){
return length;
}
};
#endif
ArrayStack.h
#ifndef _ARRAYSTACK_H_
#define _ARRAYSTACK_H_
#include "Array.h"
using namespace std;
template<class T>
class ArrayStack
{
protected:
Array<T> a;
int n;
public:
ArrayStack(int len);
virtual ~ArrayStack();
};
template<class T>
ArrayStack<T>::ArrayStack(int len){
// I don't know what to do here to implemented constructor from another class.
}
#endif
Any suggestion would be great, Thank you
Andy

unable to seperate header classes. I get "does not name a type"

I made a class with a header and a cpp and a main class. When doing so all is good! When separating a class that I will have 2 classes (header+cpp) and one main Class A (Board) does not recognize class B (IllegalCoordinateException) even though I inserted the include. This is probably a newbies question and I might lose some points, but I am stuck in finding my problem.
Here is my working code(stripped down to only the important parts):
main.cpp
#include "Board.h"
#include <iostream>
using namespace std;
int main() {
Board board1{4}; // Initializes a 4x4 board
try {
board1[{3,4}]='O'; // This should raise an exception
} catch (const IllegalCoordinateException& ex) {
cout << "Illegal coordinate" << ex.theCoordinate() << endl; // prints "Illegal coordinate: 3,4"
}
return 0;
}
Board.h
#ifndef CIRC_H
#define CIRC_H
#include <iostream>
#include <string>
using namespace std;
struct coord {
int x;
int y;
};
class IllegalCoordinateException{
coord _coord;
public:
IllegalCoordinateException(coord c){
_coord = c;
}
string theCoordinate() const{
return to_string(_coord.x)+","+to_string(_coord.y);
}
};
class xo{
char x;
public:
char getChar() const{return x;}
char& operator= (const char c){x = c;}
xo& operator= (const xo _xo){
x = _xo.getChar();
return *this;
}
void clear(){
x = '.';
}
operator char() const{
return x;
}
};
class Board{
private:
coord _coord;
xo** board;
int size;
public:
Board();
Board(int v);
~Board();
xo& operator[](coord c); // here is where I use "IllegalCoordinateException"
};
#endif
Board.cpp
#include <iostream>
#include <vector>
#include "Board.h"
using namespace std;
void freeBoard(xo** board,int size){
for(int i = 0 ; i < size ; i++){
delete[] board[i];
}
}
Board::Board()
{
size = 0;
board = new xo* [size];
}
Board::Board(int v)
{
size = v;
board = new xo* [size];
for (int i=0; i<size; i++)
{
board[i] = new xo[size];
for(int j = 0 ; j < size ; j++){
board[i][j].clear();
}
}
}
Board::~Board(){
freeBoard(board,size);
delete[] board;
}
xo& Board::operator[](coord c)
{
if(c.x < size && c.y < size)
{
return board[c.x][c.y];
}
else
{
throw IllegalCoordinateException(c);
}
}
After seperation:
main.cpp
No diff
Board.h also cpp no diff
#ifndef CIRC_H
#define CIRC_H
#include "IllegalCoordinateException.h"
#include <iostream>
#include <string>
using namespace std;
struct coord {
int x;
int y;
};
class xo{
char x;
public:
char getChar() const{return x;}
char& operator= (const char c){x = c;}
xo& operator= (const xo _xo){
x = _xo.getChar();
return *this;
}
void clear(){
x = '.';
}
operator char() const{
return x;
}
};
class Board{
private:
coord _coord;
xo** board;
int size;
public:
Board();
Board(int v);
~Board();
xo& operator[](coord c);
};
#endif
IllegalCoordinateException.h // I also seperated in my code to .h and .cpp (but ofcourse there is no real diff.
#ifndef CIRC_H
#define CIRC_H
#include <iostream>
#include "Board.h"
using namespace std;
class IllegalCoordinateException{
coord _coord;
public:
IllegalCoordinateException(coord c){ _coord = c;}
string theCoordinate() const{return to_string(_coord.x)+","+to_string(_coord.y);}
};
#endif
When doing
$ g++ -g -Og -std=c++0x main.cpp Board.cpp IllegalCoordinateException.cpp
I get:
Board.cpp: In member function ‘xo& Board::operator’:
Board.cpp:60:43: error: ‘IllegalCoordinateException’ was not declared
in this scope
throw IllegalCoordinateException(c);
How can this be? I mean I am including it in the Board.h so Board.cpp is supposed to recognize it!? I tried also to include it in Board.cpp and also make a forward declaration in Board.cpp but both were frugal.
Both of your header files have #ifndef CIRC_H / #define CIRC_H.
So when the first one is included (no matter which order), it defines CIRC_H, and when the second one is included, it gets ignored because the whole file is within #ifndef CIRC_H.
Solution: use a different macro name for each header file.

Left shift bit operator overloading

Hello guys,
I am trying to overload the left shift bit operator, <<, to do something like:
char value[] = "Hello";
value << 2;
when doing this I would like to have it printed like: "val", so to delete the last two character; My problem is I can't manage to declare my overloading function properly.
My code is:
//the .h file
#pragma once
#include <iostream>
class Operators
{
public:
char *word;
int number;
Operators(void);
Operators(char str[], int num);
~Operators(void);
void Print(void);
friend char & operator<<(char &stream, int &nr);
};
#include "StdAfx.h"
#include "Operators.h"
#include <iostream>
Operators::Operators(void)
{
word = "";
number = 0;
}
Operators::Operators(char *str, int num)
{
word = str;
number = num;
}
Operators::~Operators(void)
{
}
void Operators::Print(void)
{
printf("\nThe String: %s", word);
}
friend char & operator<<(char &stream, int &nr)
{
return stream;
}
// Operator_Overloading.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Operators.h"
#include <conio.h>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char value[] = "Hello";
Operators op(value, 2);
op.Print();
_getch();
return 0;
}
You cannot overload any of the operators if they don't involve, at least, one user defined type. Your use case involves a char[N] and an int, i.e., you can't overload any operators for these arguments.

Variable scope error when declaring friend function

Friend functions can't access variables of the classes
I'm having a problem with several friend functions not being able to access the variables in classes where they have been declared as friends.
The actual error text is:
error: 'fid' was not declared in this scope. this repeats for the other private variables.
The same error is given for three functions, read, negative, and write.
A couple of notes:
1) This lab requires that I write the code so that the functions can be used by both classes.
I'm compiling this in windows with code::blocks using g++ and I've also tried compiling my code in ubuntu using g++ from the terminal using the -g flag and I get the same error both times.
Any suggestions you have would be greatly appreciated.
Header File
#ifndef PXMUTILS_H
#define PXMUTILS_H
#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std;
typedef unsigned char uchar;
class pgm
{
public:
pgm();
~pgm();
void read(string &);
void negative();
void write(string);
friend void read (const string &);
friend void write(string);
friend void negative();
private:
int nr;
int nc;
int mval;
int ftyp;
string fid;
uchar **img;
};
class ppm
{
public:
ppm();
~ppm();
void read(string &);
void negative();
void write(string);
friend void read (const string &);
friend void write (string);
friend void negative ();
private:
int nr;
int nc;
int mval;
int ftyp;
string fid;
uchar **img;
};
#endif
C++ program
#include <cstdio>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include "pxmutils.h"
using namespace std;
typedef unsigned char uchar;
uchar ** newimg(int nr, int nc, int ftyp)
{
uchar **img=new uchar *[nr];
img[0]=new uchar [nr*nc*ftyp];
for(int i=1; i<nr; i++)
{
img[i]=img[i-1]+nc*ftyp;
}
return img;
}
void deleteimg(uchar **img)
{
if(img)
{
if(img[0])
{
delete [] img[0];
}
delete [] img;
}
}
void read (const string &fname)
{
ifstream fin(fname.c_str(), ios::in);
if(!fin.is_open())
{
cerr<<"Could not open "<<fname<<endl;
exit(0);
}
fin >>fid
>>nc
>>nr
>>mval;
while (fin.get() != '\n') { /*skip to EOL */ }
img=newimg(nr, nc);
fin.read((char *)img[0], nr*nc);
fin.close();
}
void set_cmap(string mname)
{
}
void negative()
{
for(int i=0; i<nr; i++)
{
for(int j=0; j<nc; j++)
{
int t=img[i][j];
img[i][j]=(255-t);
}
}
}
void write(string fname)
{
ofstream fout (fname.c_str(), ios::out);
size_t dp;
if ((dp = fname.rfind(".pgm")) != string::npos)
{
fout<<"P5"<<endl;
}
if((dp= fname.rfind(".ppm")) != string::npos)
{
fout<<"P6"<<endl;
}
fout<<nc<<" "<<nr<<endl;
fout<<mval<<endl;
for(int i=0; i <nr; i++)
{
for (int j=0; j<nc; j++)
{
fout<<img[i][j]<<" ";
}
fout<<endl;
}
fout.close();
}
pgm::pgm()
{
nr=0;
nc=0;
mval=0;
ftyp=1;
fid="";
img=NULL;
}
pgm::~pgm()
{
deleteimg(img);
}
ppm::ppm()
{
nr=0;
nc=0;
mval=0;
ftyp=1;
fid="";
img=NULL;
}
ppm::~ppm()
{
deleteimg(img);
}
Program to test functions
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
#include "pxmutils.h"
int main(int argc, char *argv[])
{
if (argc == 1) {
cerr << "No input file specified!\n";
exit(0);
}
string fname = argv[1];
size_t dp;
if ((dp = fname.rfind(".pgm")) == string::npos) {
cout << "PGM error: file suffix " << fname
<< " not recognized\n";
exit(0);
}
fname.erase(dp);
pgm img_g;
ppm img_c;
img_g.read(fname+".pgm");
if (argc == 3)
img_c.set_cmap(argv[2]);
img_c = img_g;
img_g.negative();
img_g.write(fname+"_n.pgm");
img_c.write(fname+"_c.ppm");
}
fin >>fid
>>nc
>>nr
>>mval;
while (fin.get() != '\n') { /*skip to EOL */ }
In this code, fid, nc, nr etc are undefined. You need to use the class instance to be able to access them, they don't exist by themselves.
Your functions don't accept the class objects as parameters, so how are you going to read into them?
You should have another think of your design. It is best to avoid friend functions if possible,
You need to go a bit back to basics. When you define non-static members of a class you are defining attributes or operations of the objects of the class, but those attributes don't exist by themselves, only as part of the instances of the class.
This concept is orthogonal to access and access specifiers, that is, this is so regardless of the members being public, protected or private. Once you have an instance, when your try to access those members the access specifiers come into play, and there is where friendship comes into play: it will grant your code access to members that would otherwise be inaccessible (private or protected outside of the inheritance hierarchy).
The problem in your code is that you don't have an object, and thus cannot access the members of the object. You will need to either create or pass an object of the appropriate type to the functions.
There are other problems in the code, like for example, the memory allocations inside newimg look a little suspicious (what were you intending to allocate?) but that is outside of the scope of this question.