C++ friend function can't access private members - c++

This is supposed to be a string class with a bunch of operators and functions, including two friend functions. And those two cause some trouble for me, because the compiler says that they can not access the private members. Here is my string.h:
#include <iostream>
#ifndef STR_H
#define STR_H
namespace MyStr
{
class Str
{
private:
unsigned int length;
char *data;
public:
Str();
Str(const Str&);
Str(const char*);
Str(char c, unsigned int db);
~Str();
char* cStr() const;
unsigned int getLength() const;
lots of irrevelant functions here...
friend int operator/ (const Str&, char);
friend std::ostream& operator<< (std::ostream&, const Str&);
};
}
#endif /* STR_H */
here is the main.cpp:
#include <iostream>
#include "Str.h"
using namespace std;
using namespace MyStr;
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
{
out<<str.data[i];
}
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
{
if(str.data[i]==c) return i;
}
return -1;
}
This code won't compile, the compiler claiming that the Str members are private.

You should pay more attention to namespaces.
class Str {
private:
unsigned int length;
char *data;
public:
Str(){}
Str(const Str&){}
Str(const char*){}
Str(char c, unsigned int db){}
// maybe something more...
friend int operator/ (const Str&, char);
friend std::ostream& operator<< (std::ostream&, const Str&);
};
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
out<<str.data[i];
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
if(str.data[i]==c) return i;
return -1;
}
int main()
{
Str s;
cout<<s;
return 0;
}
You get error because of the unmatched namespaces. If you prefer to stick with MyStr then you should add namespace MyStr to overloaded friend operators. This is how you can do it: (operators should be defined within namespace MyStr)
namespace MyStr {
ostream& operator<< (ostream& out,const Str& str)
{
for (int i=0; i<str.length; i++)
{
out<<str.data[i];
}
out<<endl;
return out;
}
int operator/ (const Str& str, char c)
{
for (int i=0; i<str.length; i++)
{
if(str.data[i]==c) return i;
}
return -1;
}
}

When you declare the friend functions inside Str they are considered to be in the immediately enclosing namespace, MyStr.
The operators you define are in the global namespace, so the compiler believes that those are two entirely different operators, and not the friends.
You can solve this by adding
namespace MyStr
{
}
around the operators in the .cpp file.

Related

how to write operator overloading for operator [] in c++

I want to make three[0]='p'; work in the code below. I think I have to make an operator overloading for that but I don't know how to do. What I want to get is to change first index of "Lottery winner!" to 'p'. (To get "pottery winner!").
#include<iostream>
#include<cstring>
using namespace std;
class str
{
char* a;
public:
str(char *aa=""){
this->a = new char[strlen(aa)+1];
strcpy(a,aa);
}
~str(){
delete a;
}
friend ostream& operator<<(ostream &out, str &aa);
friend istream& operator>>(istream &in, str &aa);
};
ostream& operator<<(ostream &out, str &aa){
out<<aa.a;
return out;
}
istream& operator>>(istream &in, str &aa){
in>>aa.a;
return in;
}
void main(){
str three("Lottery winner!");
three[0]='p';
cout<<three<<endl;
}
This is the general signature of the operator[]:
T& operator[](any_type);
In your context it would look like this:
struct str {
...
char& operator[](std::size_t pos) {
return a[pos];
}
};
class str
{
// ...
public:
// ...
char& operator[] (int x)
{
// add array out-of-bounds check here if you like to ...
return a[x];
}
}
operator char*()
{
return a;
}
Could also work

reverse function doesn't reverse the referenced string of a class instantiation

I'm trying to reverse the string from the FunnyNumber class. The problem is that when I call the method reverse in main on f2, it doesn't reverse the f2 string. But when I print out the reversed string from the reverse method implementation, it works. Also I overloaded the << operator to print out the string value in the class Number which is inherited in FunnyNumber class. Any help would be appreciated.
#ifndef NUMBER_H
#define NUMBER_H
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class Number {
public:
// Make a number with value 0
Number();
// Make a number with value val
Number(string val);
// Get the number's value
virtual string getValue() const;
// Print this number to the stream
virtual void print(ostream& stream) const;
// Read this number from the stream
virtual void read(istream& stream);
// Overload the insertion operator
friend ostream& operator <<(ostream& outs, const Number& n);
// Overload the extraction operator
friend istream& operator >> (istream& ins, Number& n);
protected:
string value;
};
#endif
Number::Number()
{
value = "";
}
Number::Number(string args)
{
value = args;
}
string Number::getValue()const
{
return value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
n.print(outs);
return outs;
}
void Number::print(ostream& stream)const
{
stream << getValue();
}
void Number::read(istream& stream)
{
stream >> value;
}
istream& operator >> (istream& ins, Number& n)
{
n.read(ins);
return ins;
}
#ifndef FUNNYNUMBER_H
#define FUNNYNUMBER_H
#include<iostream>
#include<string>
#include"Number.h"
#include<algorithm>
using namespace std;
class FunnyNumber : public Number
{
public:
FunnyNumber();
FunnyNumber(string val);
virtual string operator+(const FunnyNumber &other)const;
virtual bool operator==(const FunnyNumber &other)const;
void reverse();
int find_first_not_this(char a);
protected:
string value;
};
#endif // !FUNNYNUMBERS_H
FunnyNumber::FunnyNumber()
{
value = "";
}
FunnyNumber::FunnyNumber(string val) : Number(val)
{
value = val;
}
string FunnyNumber::operator+ (const FunnyNumber& other)const
{
return getValue() + other.getValue();
}
int FunnyNumber::find_first_not_this(char a)
{
int pos = 0;
for(int i = 0; i < value.length(); i++)
{
if(value[i] != a)
{
pos = i;
return pos;
}
}
return pos;
}
bool FunnyNumber::operator==(const FunnyNumber& other)const
{
bool isEqual = true;
for (int i = 0; i < other.getValue().length(); i++)
{
bool found = false;
for (int j = 0; j < getValue().length(); j++)
{
if(getValue()[j] == other.getValue()[i])
{
found = true;
break;
}
}
if(!found)
{
isEqual = found;
return isEqual;
}
}
return isEqual;
}
void FunnyNumber::reverse()
{
std::reverse(value.begin(), value.end());
value.erase(0, find_first_not_this('0'));
}
#include <iostream>
#include<string.h>
#include "FunnyNumber.h"
using namespace std;
int main()
{
FunnyNumber f2;
f2 = FunnyNumber("223");
f2.reverse();
cout<<"Reversed value "<<f2<<endl;
system("pause");
return 0;
}
output is 223 instead of 322
Your FunnyNumber stores the value twice, once in a subobject of type Number, and once in string FunnyNumber::value.
Your reverse function modifies the second one, but doesn't have any effect on the Number base subobject. And then the only output function you call is working on the Number base subobject, and knows nothing about string FunnyNumber::value. That's why what is printed is not the result of reversal.
the overloaded operator << is a friend function on the Number class and friend functions are not inherited.
class Number {
public:
// Make a number with value 0
Number();
// Make a number with value val
Number(string &val);
// Get the number's value
virtual string getValue() const;
// Print this number to the stream
virtual void print(ostream& stream) const;
// Read this number from the stream
virtual void read(istream& stream);
// Overload the insertion operator
friend ostream& operator <<(ostream& outs, const Number& n);
// Overload the extraction operator
friend istream& operator >> (istream& ins, Number& n);
protected:
string *value;
};
Number::Number()
{
value = NULL;
}
Number::Number(string &args)
{
value = &args;
}
string Number::getValue()const
{
return *value;
}
ostream& operator <<(ostream& outs, const Number& n)
{
n.print(outs);
return outs;
}
void Number::print(ostream& stream)const
{
stream << getValue();
}
void Number::read(istream& stream)
{
stream >> *value;
}
istream& operator >> (istream& ins, Number& n)
{
n.read(ins);
return ins;
}

How do I access an array in my header file from my implementation file when overloading << operator?

If I take out the line where I am outputting the contents of data[], it compiles fine. I seem to be having trouble understanding accessing the array through the implementation file. Any help would be apprecciated.
implementation file function:
ostream& operator << (ostream& output, const Bag& b1)
{
for(int i = 0; i< b1.used; i++)
{
output <<Bag.data[i]<<" "; // LINE OF ERROR
}
output<<endl;
return output;
}
header file:
#ifndef BAG_H
#define BAG_H
#include <cstdlib>
#include <fstream>
namespace greg_bag{
using namespace std;
class Bag
{
public:
typedef int value_type;
typedef std:: size_t size_type;
static const size_type CAPACITY = 30;
Bag(){used = 0;}
void erase();
bool erase_one(const value_type& target);
void insert (const value_type& entry);
//void operator += (const bag& addend);
//size_type size()const {return used;}
//size_type count(const value_type& target) const;
//bag operator +(const bag& b1, const bag& b2);
friend ostream& operator << (ostream&, const Bag&);
private:
value_type data[CAPACITY];
size_type used;
};
}
#endif
error message:
error: expected primary-expression before '.' token|
data is not a static variable so that you can use it directly with class name.
data is different for each instance of a class. Use the following code :
ostream& operator << (ostream& output, const Bag& b1)
{
for(int i = 0; i< b1.used; i++)
{
output <<b1.data[i]<<" "; // LINE OF ERROR
}
output<<endl;
return output;
}

ostream& does not name a type error. What am I doing wrong here?

I am a learner. I am working on operator overloading. I am trying to write a code for overloading [] and print the elements in the member array. But when I am overloading << to print the member array, I get the error, ostream& does not have a type. What am I doing wrong here? Also what can I do if I have a class that has two member arrays? Here is my code below:
#include <iostream>
#include <cassert>
class Digit
{
private:
int digit1[3]{0};
public:
int& operator[](const int index);
ostream& operator<<(ostream& out);
};
int& Digit::operator[](const int index)
{
return digit1[index];
}
ostream& Digit::operator<<(ostream& out)
{
int loop;
out << "{";
for (loop = 0; loop < 10; loop++)
{
out << digit1[loop] << " ";
}
out << "}";
return o;
}
int main()
{
using namespace std;
Digit n;
n[0] = 4;
n[1] = 3;
n[2] = 4;
n << cout;
return 0;
}
You have put
int main()
{
using namespace std;
//....
This cannot be seen where you declare your << operator. One solution is to change the signature to include the namesape:
In the class:
std::ostream& operator<<(std::ostream& out)
and then
std::ostream& Digit::operator<<(std::ostream& out)
While you are there, I wonder if it should be const?
you must be forgetting the namespace
try - std::ostream &operator<<(std::ostream &out)

Overloading << error

I am kind of newbie to programming migrated from legacy turbo c++ to VS C++2012,I have a tough time catching up and i wanted to emulate the string library for TC. But i cant make the insertion operator work in this code....Please help Out. Could you tell the mistake i made in this code. And also why are we returning the object via reference for overloading.
#include<iostream>
#include<string>
namespace String
{
class string
{
char word[100];
int size;
public:
string()
{
size=0;
}
string(int sz)
{
size=sz;
}
string(char *Word)
{
strcpy(word,Word);
size=sizeof(*Word);
}
~string()
{
}
string &operator+(string Add)
{
strcat(word,Add.word);
return *this;
}
string &operator=(char *Word)
{
strcpy(word,Word);
return *this;
}
/*
ostream &operator<<(ostream &sout,string Show)
{
sout<<Show.word;
return sout;
}
*/
void Show()
{
std::cout<<word;
}
};
}
void main()
{
String::string A="ABCDEF";
String::string B="GHIJK";
String::string C;
C=A+B;
C.Show();
std::cin.ignore(2);
//std::cout<<C;
}
You should declare operator<< as a non-member function, because ostream will be taken as the 1st argument for operator<<, a user define type's member function can't satisfy it.
namespace String
{
class string
{
...
public:
ostream& put(ostream &sout) { sout << word; return sout; }
};
ostream& operator<<(ostream& sout, string Show) { return Show.put(sout); }
}
The output operator << has to be overloaded in the namespace, not the class itself if you want to be able to use it like so:
cout << my_class_object;
So, in the declaration of your class (string.h) add this line:
ostream &operator<<(ostream & sout,const string & Show);
And then in the definition file (string.cpp) in your namespace, not the class itself, ad this function:
ostream & operator<<( ostream & out, const bigint & data )
{
// the printing implementation
}