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.
Related
I am trying to create a function that returns in main.cpp in the header and .cpp file and run it in the main function.
This process I do works on main.
#include <iostream>
#include <sstream>
#include "Cards.h"
using namespace std;
//this function returns array
int *function1(){
int a=12;
int b=13;
int c=14;
static int list[3]={a,b,c};
return list;
}
int main(int argc, const char * argv[]) {
int *list;
list=function1();
cout<<list[1]<<endl;
return 0;
}
However, I cannot do these in a header and a separate cpp file.
I have a Cards header
#ifndef Cards_H
#define Cards_H
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
class Cards{
public:
char suit; //A,H,D,C,S. A is empty card
int number; //00-13
int visibilty;//0 - 1. O invisible 1 is visible
int * function2();
};
#endif
This is the class cpp file
#include "Cards.h"
using namespace std;
//function
int Cards:: function2(){
int a=12;
int b=13;
int c=14;
int list[3]={a,b,c};
return list; // error code Cannot initialize return object of type 'int Cards::*' with an lvalue of type 'int [3]'
}
How do I fix this problem and run it in main?
As pointed out in the comments, there is already a SO thread
Return array in a function
which handles your issue.
If your really want to use C arrays then your program shall look like:
Cards_CStyle.h:
#ifndef Cards_CStyle_H
#define Cards_CStyle_H
using namespace std;
class Cards {
public:
int* function2(int arr[]);
};
#endif
Cards_CStyle.cpp:
#include "Cards_CStyle.h"
using namespace std;
//function
int* Cards::function2(int arr[]){
int a=12, b=13, c=14;
arr[0] = a;
arr[1] = b;
arr[2] = c;
return arr;
}
main_CStyle.cpp:
#include <iostream>
#include "Cards_CStyle.h"
using namespace std;
int main(int argc, const char * argv[]) {
int arr[3]; // Take care that all your functions use size <= 3
Cards cards;
int* list=cards.function2(arr);
cout<<list[1]<<endl;
return 0;
}
As recommended in the comments, you should use the containers of the STL, e.g. array for fixed length or vector for variable length. Assuming that fixed length of 3 will be fine for you, then your code would be looking like this:
Cards_STLStyle.h:
#ifndef Cards_STLStyle_H
#define Cards_STLStyle_H
#include<array>
using namespace std;
typedef array<int, 3> my_array;
class Cards {
public:
my_array function2();
};
#endif
Cards_STLStyle.cpp:
#include "Cards_STLStyle.h"
using namespace std;
//function
my_array Cards::function2(){
int a=12, b=13, c=14;
return my_array { a,b,c};
}
main_STLStyle.cpp:
#include <iostream>
#include <array>
#include "Cards_STLStyle.h"
using namespace std;
int main(int argc, const char * argv[]) {
Cards cards;
my_array list=cards.function2();
cout<<list[1]<<endl;
return 0;
}
Please find more information here:
array
#include "stdafx.h"
#include <iostream>
using namespace std;
#include <string.h>
class Array
{
public:
int Length;
char *Arrp;
Array(char *str)
{
Length=strlen(str);
Arrp=str;
}
char & operator[](int index);
};
char & Array::operator[](int index)
{
if(index>=Length||index<0)
{
cout<<"Index "<<index<<" error."<<endl;
return Arrp[0];
}
return Arrp[index];
}
int _tmain(int argc, _TCHAR* argv[])
{
Array a("Good");
cout<<a.Arrp[6]<<endl;
return 0;
}
It doesn't get into the overload function of [] at all. I compare it with lots of examples but what I write never functions.
How can I proceed further?
You're not calling the overloaded function but are directly reading the array itself.
Try:
cout<<a[6]<<endl;
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;
im getting the above error for the following code. Please help me with what i am doing wrong. This code has nested structures. For now it generates name for the generation structure based on the input given by the user.
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <limits>
#include <stdio.h>
#include <sstream>
using namespace std;
using std::stringstream;
struct rootset {
double totSize;
const char *rStrtPtr;
const char *rEndPtr;
struct generations {
double totSize;
const char *genStrtPtr;
const char *genEndPtr;
int numOfGen;
int genName;
struct object {
double objSize;
const char *objStrtPtr;
const char *objEndPtr;
string id;
char markBit;
char objPtr;
struct freeList {
double freeSpace;
int flNumb;
};
};
} generation;
};
int main()
{
int gen =0;
cin >> gen;
rootset* pRootSet = (rootset*)malloc(1200);
for( i=0; i<gen; i++) {
stringstream out;
out << i;
string s = out.str();
string foo = "generation";
pRootSet->generation.genName = foo.append(s); /*Error is here*/
cout<<"foo: "<<foo<<endl;
}
}
i am trying to print this answer:
4
foo: generation0
foo: generation1
foo: generation2
foo: generation3
generation.genName is of INT type while you want to pass a string value without any conversion, that's why it gives it an error. Solution: do the conversion before.
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.