Trouble with friend in C++ - c++

Ah yes "friend" the most dreaded of keywords, not quite object oriented, not quite procedural. Well here it is making trouble again, I have every possible warning I could think of on, and all the GCC can tell me is that read poly() is not declared in this scope (main.cpp). Can anyone help me figure out what I'm doing wrong? I've tried rearranging the code in read poly, but that doesn't help, no other function prototypes seem to change this behaviour either. I just know I'm going to be hitting myself when I figure out what it is.
//main.cpp
#include "Polynomial.h"
int main()
{
Polynomial test = readPoly();
}
//Polynomial.h
class Polynomial
{
public :
/** creates the zero Polynomial and sets the default output character*/
Polynomial();
/** creates the constant Polynomial c */
Polynomial( int c );
/** creates a Polynomial with one term c*x^d */
Polynomial(int c, int d);
Polynomial(const Polynomial& toCopy);
friend const Polynomial readPoly();
void insert(Term* term);
}
//Polynomial.cpp
const Polynomial readPoly()
{
cout << "How many terms? ";
int termQty = 0;
cin >> termQty;
int coefficient,degree;
Polynomial newPoly;
for (int n = 0; n <= termQty; n++)
{
cin >> coefficient >> degree;
newPoly.insert(new Term(coefficient,degree));
newPoly.degreeCached = max(degree, newPoly.degreeCached);
}
return newPoly;
}

A friend declaration declares a function to exist in the nearest
enclosing namespace scope, but it only makes the declaration visible
within the class or through ADL. And since the function doesn't have
any arguments which use Polynomial, ADL won't find it. Just add a
declaration of the function in the surrounding namespace scope. Or make
it a static member, rather than a friend—in this case, it seems
more appropriate (to me, at least). In that case, you would call it
with Polynomial::readPoly() (or just Polynomial::read(), since the
scope resolution says explicitly what we are reading). Such static
members are probably the most usual implementation of the factory
function idiom.

Looks like you haven't declared readPoly() before using it. You can re-arrange the source (some more) so that it appears above main() or better still declare it before use:
//Polynomial.h
class Polynomial
{
....
};
extern const Polynomial readPoly();

readPoly indeed is not declared in this scope. Add a function declaration in the header. The friend clause only tells that this function can access private members, but it does not declare the function itself. So in the main the function is really not declared.

Related

How to go about hiding "helper functions" from the interface of a header file

I'm trying to implement a Money class that has a representation for money (as in $13.00, $18.92, etc.) and a set of operations. Here's the header file so far:
#include <iostream>
namespace Currency {
class Money {
private:
long int total_cents = 0;
public:
Money();
Money(long int c);
Money(long int d, int c);
long int get_cents() const {return total_cents;}
//Money(float dollars); // TODO
};
std::ostream& operator<<(std::ostream& os, const Money& m);
std::istream& operator>>(std::istream& is, const Money& m);
// Returns the total number of cents in $d.c
long int to_cents(long int d, int c);
}
My issue is that I don't intend for the last helper function to be apart of the interface, so I want to define it only in the cpp file as an implementation function. I only want the constructor Money(long int, int) to call it, and the user will only ever deal with the Money class (I'm gonna add some more useful operations later), so they won't have any reason to call to_cents.
My worry is that if I declare it in the cpp file and the user creates another function with the same name in a separate file, there will be a name conflict, which will cause a linker error. But I can't think of any other way to hide to_cents from the interface, apart from putting it as a private member of Money. It wouldn't make much sense to make it a private member of Money since it doesn't read or write to any of its data members. The other alternative is to write out the function in the constructor, but I think it serves as a logically separate computation, so it should be its own function. What is the best way to go from here?
Let me know if there's anything I should elaborate on, thank you!
You can define a function local to a source file by wrapping it in an anonymous namespace:
// in your cpp file:
namespace {
long to_cents(long d, int c) {
// ...
}
}
You can also do the same thing by making it a static function:
// in your cpp file
static long to_cents(long d, int c) {
// ...
}

Trouble implementing min Heaps in C++

I'm trying to implement a minheap in C++. However the following code keeps eliciting errors such as :
heap.cpp:24:4: error: cannot convert 'complex int' to 'int' in assignment
l=2i;
^
heap.cpp:25:4: error: cannot convert 'complex int' to 'int' in assignment
r=2i+1;
^
heap.cpp: In member function 'int Heap::main()':
heap.cpp:47:16: error: no matching function for call to 'Heap::heapify(int [11], int&)'
heapify(a,i);
^
heap.cpp:47:16: note: candidate is:
heap.cpp:21:5: note: int Heap::heapify(int)
int heapify(int i) //i is the parent index, a[] is the heap array
^
heap.cpp:21:5: note: candidate expects 1 argument, 2 provided
make: * [heap] Error 1
#include <iostream>
using namespace std;
#define HEAPSIZE 10
class Heap
{
int a[HEAPSIZE+1];
Heap()
{
for (j=1;j<(HEAPISZE+1);j++)
{
cin>>a[j];
cout<<"\n";
}
}
int heapify(int i) //i is the parent index, a[] is the heap array
{
int l,r,smallest,temp;
l=2i;
r=2i+1;
if (l<11 && a[l]<a[i])
smallest=l;
else
smallest=i;
if (r<11 && a[r]<a[smallest])
smallest=r;
if (smallest != i)
{
temp = a[smallest];
a[smallest] = a[i];
a[i]=temp;
heapify(smallest);
}
}
int main()
{
int i;
for (i=1;i<=HEAPSIZE;i++)
{
heapify(a,i);
}
}
}
Ultimately, the problem with this code is that it was written by someone who skipped chapters 1, 2 and 3 of "C++ for Beginners". Lets start with some basics.
#include <iostream>
using namespace std;
#define HEAPSIZE 10
Here, we have included the C++ header for I/O (input output). A fine start. Then, we have issued a directive that says "Put everything that is in namespace std into the global namespace". This saves you some typing, but means that all of the thousands of things that were carefully compartmentalized into std:: can now conflict with names you want to use in your code. This is A Bad Thing(TM). Try to avoid doing it.
Then we went ahead and used a C-ism, a #define. There are times when you'll still need to do this in C++, but it's better to avoid it. We'll come back to this.
The next problem, at least in the code you posted, is a misunderstanding of the C++ class.
The 'C' language that C++ is based on has the concept of a struct for describing a collection of data items.
struct
{
int id;
char name[64];
double wage;
};
It's important to notice the syntax - the trailing ';'. This is because you can describe a struct and declare variables of it's type at the same time.
struct { int id; char name[64]; } earner, manager, ceo;
This declares a struct, which has no type name, and variables earner, manager and ceo of that type. The semicolon tells the compiler when we're done with this statement. Learning when you need a semicolon after a '}' takes a little while; usually you don't, but in struct/class definition you do.
C++ added lots of things to C, but one common misunderstanding is that struct and class are somehow radically different.
C++ originally extended the struct concept by allowing you to describe functions in the context of the struct and by allowing you to describe members/functions as private, protected or public, and allowing inheritance.
When you declare a struct, it defaults to public. A class is nothing more than a struct which starts out `private.
struct
{
int id;
char name[64];
double wage;
};
class
{
public:
int id;
char name[64];
double wage;
};
The resulting definitions are both identical.
Your code does not have an access specifier, so everything in your Heap class is private. The first and most problematic issue this causes is: Nobody can call ANY of your functions, because they are private, they can only be called from other class members. That includes the constructor.
class Foo { Foo () {} };
int main()
{
Foo f;
return 0;
}
The above code will fail to compile, because main is not a member of Foo and thus cannot call anything private.
This brings us to another problem. In your code, as posted, main is a member of Foo. The entry point of a C++ program is main, not Foo::main or std::main or Foo::bar::herp::main. Just, good old int main(int argc, const char* argv[]) or int main().
In C, with structs, because C doesn't have member functions, you would never be in a case where you were using struct-members directly without prefixing that with a pointer or member reference, e.g. foo.id or ptr->wage. In C++, in a member function, member variables can be referenced just like local function variables or parameters. This can lead to some confusion:
class Foo
{
int a, b;
public:
void Set(int a, int b)
{
a = a; // Erh,
b = b; // wat???
}
};
There are many ways to work around this, but one of the most common is to prefix member variables with m_.
Your code runs afoul of this, apparently the original in C passed the array to heapify, and the array was in a local variable a. When you made a into a member, leaving the variable name exactly the same allowed you not to miss the fact that you no-longer need to pass it to the object (and indeed, your heapify member function no-longer takes an array as a pointer, leading to one of your compile errors).
The next problem we encounter, not directly part of your problem yet, is your function Heap(). Firstly, it is private - you used class and haven't said public yet. But secondly, you have missed the significance of this function.
In C++ every struct/class has an implied function of the same name as the definition. For class Heap that would be Heap(). This is the 'default constructor'. This is the function that will be executed any time someone creates an instance of Heap without any parameters.
That means it's going to be invoked when the compiler creates a short-term temporary Heap, or when you create a vector of Heap()s and allocate a new temporary.
These functions have one purpose: To prepare the storage the object occupies for usage. You should try and avoid as much other work as possible until later. Using std::cin to populate members in a constructor is one of the most awful things you can do.
We now have a basis to begin to write the outer-shell of the code in a fashion that will work.
The last change is the replacement of "HEAPSIZE" with a class enum. This is part of encapsulation. You could leave HEAPSIZE as a #define but you should expose it within your class so that external code doesn't have to rely on it but can instead say things like Heap::Size or heapInstance.size() etc.
#include <iostream>
#include <cstdint> // for size_t etc
#include <array> // C++11 encapsulation for arrays.
struct Heap // Because we want to start 'public' not 'private'.
{
enum { Size = 10 };
private:
std::array<int, Size> m_array; // meaningful names ftw.
public:
Heap() // default constructor, do as little as possible.
: m_array() // says 'call m_array()s default ctor'
{}
// Function to load values from an istream into this heap.
void read(std::istream& in)
{
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
}
return in;
}
void write(std::ostream& out)
{
for (size_t i = 0; i < Size; ++i)
{
if (i > 0)
out << ','; // separator
out << m_array[i];
}
}
int heapify(size_t index)
{
// implement your code here.
}
}; // <-- important.
int main(int argc, const char* argv[])
{
Heap myHeap; // << constructed but not populated.
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
myHead.write(std::cout);
return 0;
}
Lastly, we run into a simple, fundamental problem with your code. C++ does not have implicit multiplication. 2i is the number 2 with a suffix. It is not the same as 2 * i.
int l = 2 * i;
There is also a peculiarity with your code that suggests you are mixing between 0-based and 1-based implementation. Pick one and stick with it.
--- EDIT ---
Technically, this:
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
is poor encapsulation. I wrote it this way to draw on the original code layout, but I want to point out that one reason for separating construction and initialization is that it allows initialization to be assured that everything is ready to go.
So, it would be more correct to move the heapify calls into the load function. After all, what better time to heapify than as we add new values, keeping the list in order the entire time.
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
heapify(i);
}
Now you've simplified your classes api, and users don't have to be aware of the internal machinery.
Heap myHeap;
myHeap.load(std::cin);
myHeap.write(std::cout);

scope of class variable defined in a function in C++

Consider the following C++ code:
// friend functions
#include <iostream>
using namespace std;
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}
CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres; // Defined without using new keyword. This means scope of this variable of in this function, right ?
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
return 0;
}
The variable "CRectangle rectres" is defined in the function "CRectangle duplicate".
Does this mean that the scope of the variable "CRectangle rectres" is limited to the function only ? (since it has been defined without using new keyword)
If answer to above question is yes, then how can it be returned (since it is a local variable) ?
Credits : Code take from : http://www.cplusplus.com/doc/tutorial/inheritance/
Your question as to 1 & 2 has been adequately answered by Patrick, but I thought I could expand a bit:
The way MOST compilers work [1] when you return a struct or class object is that the calling function passes in a pointer argument (that is hidden from view) for the "return here" value. So the called function will copy the result into the place supplied by the calling code - the actual copy is done by the copy constructor of the class.
note 1: that the C++ standard doesn't say how the compiler should do this, and if the compiler can produce magical code that just moves the bits by using "The Force" from Star Wars then that is also allowed according to the standard.
Yes, it is a local variable.
If you return a copy of rectres

i am trying to complete my assignment.which says In a Distance class create an overloaded * operator

I am trying to complete my assignment.which says In a Distance class create an overloaded * operator so that two distances can be multiplied together. Here is my program:
#include<iostream>
using namespace std;
class distance
{
private:
int a;
public:
distance():a(10){}
distance(int x)
{
a=x;
}
void print()
{
cout<<"\n a = "<<a<<" \n ";
}
distance operator *(distance);
};
distance distance :: operator *(distance d)
{
a=a*d.a;
return distance(a);
}
int main()
{
distance d1,d2,d3;
d1.print();
d2.print();
d3.print();
d3=d1 * d2;
d3.print();
return 0;
}
But I get a compilation error saying:
'distance' : ambiguous symbol.
when I run it on VC++
But it runs fine on Turbo C (by minor change: #include<iostream.h>).
Please explain where am I getting wrong. Thanks in advance.
There's already a function called std::distance, which you're bringing into scope through using namespace std and which clashes with your distance class.
Call your class something else (e.g. Distance) or, better yet, remove using namespace std.
P.S. This is a nice illustration of why using namespace X in this manner usually isn't a good idea.
Remove using namespace std; from your code, and prefix the appropriate symbols with std::. There is an std::distance name defined for iterators in the standard templates.
(Your operator* would be better if it took a distance const& d as its parameter.)
distanceis also the name of a template function in the standard libary. I strongly suspect that since you are using namespace std; it's ambiguous.
You don't want to declare a name that is injected by another namespace in the same scope as others have mentioned. Because its name hides the namespace member, you can either use :: scope operator to refer to your own name or you can change the name of your class. Assuming if you named distance as distance1 you want to write your multiplication operator as:
distance1 distance1::operator* (const distance1 &d1)
{
return distance1(a*d1.a);
}

Access private variable in global scope

In this below code, the foo function in the global scope tries to access the private variables of a Box, which ofcourse doesn't work. I have to make the foo function work with one line of code at the place show code for a school assignment.
#include <iostream>
using namespace std;
class Box {
int x,y;
public:
Box(int xi,int yi) {x=xi;y=yi;}
// One line of code to make foo(Box, Box) work
};
bool foo(Box l,Box r) {return (l.x*l.y)>(r.x*r.y);}
int main(int argc, char* argv[]) {
Box b1(3,4),b2(1,2);
if (foo(b1,b2)) cout << "b1>b2\n";
return cin.get();
}
Look into the friend keyword.
First off, this is not a priori a dirty thing. The placement of the comment line already indicates that the class Box controls who is allowed to touch its privates (pun intended).
Secondly, since this is a school assignment I think that the solution should have been mentioned in class: this can be achieved using a friend declaration.
Declare foo as a friend function inside Box
#include<iostream>
class Box {
int x,y;
public:
Box(int xi,int yi) :x(xi),y(yi){}// Always use initializer list for initializing data members, i.e. prefer initialization over assignment
friend bool foo(Box,Box);// friend functions can access private members
};
bool foo(Box l,Box r) // friend keyword not to be written while defining the function
{return (l.x*l.y)>(r.x*r.y);}
int main(int argc, char* argv[]) {
Box b1(3,4),b2(1,2);
if (foo(b1,b2)) std::cout << "b1>b2\n";
return std::cin.get();
}
In addition to the other answers involving friends, a better answer for the long term (although not a one-line change) would be for Box to overload the appropriate comparison operators.