Is this possible?
AndroidZ (62)
Dec 23, 2011 at 2:04am UTC
I need a global function: void print_stack( Stack const * pstack );
to print out each element of a list. It needs to access private members. Can it be a friend AND global?
What do I need to make it a friend of if I do?
node.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
#ifndef NODE_H
#define NODE_H
// The node class for singly-linked list of integers
#include <cassert>
#include <iostream>
using namespace std;
class Node
{
//friend void print_list( Node const& head );
public :
Node* pnext;
int data;
// Constructor taking initial value:
Node( int value = 0 )
: pnext( NULL ), data( value )
{
}
// Copy constructor:
Node( Node const & other )
: pnext( NULL ), data( other.data )
{
}
// Insert new node in front:
void insert( Node* newNode )
{
newNode->pnext = pnext;
pnext = newNode;
}
// Remove node in front:
void remove_next()
{
if ( pnext == NULL ) return ;
Node* obsolete = pnext;
this ->pnext = obsolete->pnext;
// Make node "single":
obsolete->pnext = NULL;
}
// Remove other node in front:
bool remove( Node* other )
{
Node* previous = this ;
Node* iter = pnext;
while ( iter != other ) {
if ( iter == NULL )
return false ;
previous = iter;
iter = iter->pnext;
}
previous->pnext = iter->pnext;
// Make node "single" after successful removal:
other->pnext = NULL;
return true ;
}
// Measure distance to other node:
int distance( Node const * other ) const
{
int hops = 1;
Node const * iter = pnext;
while ( iter != other ) {
if ( iter == NULL ) {
// Don't count this last hop:
return hops - 1;
}
iter = iter->pnext;
++hops;
}
return hops;
}
// Calculate number of nodes in the list:
size_t size() const
{
return distance( NULL );
}
};
//void print_list( Node const& head );
#endif //NODE_H
stack.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#if (!defined(STACK_H))
#define STACK_H
#include "node.h"
class Stack {
Node head;
public :
// Push new element to the stack:
void push( int value );
// Pop element from the stack:
int pop();
// Writeable access to element on top of the stack:
int & top();
// Read-only access to element on top of the stack:
int top() const ;
// Return stack size:
size_t size() const ;
// Is stack empty?
bool is_empty() const ;
friend void print_stack( Stack const * pstack );
};
#endif
stack.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#include "node.h"
#include "stack.h"
using namespace std;
void Stack::push(int n){
//Node * ptemp = new Node(value);
//head.insert(Node(value))
head.insert(new Node(n));
}
int Stack::pop(){
Node* ptr_obsolete_node = head.pnext;
head.remove_next();
delete ptr_obsolete_node;
}
int & Stack::top(){
return head.pnext->data;
}
int Stack::top() const {
return head.pnext->data;
}
size_t Stack::size() const {
return head.size() - 1;
}
bool Stack::is_empty() const {
return size() == 0;
}
main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include <cassert>
#include "Node.h"
#include "Stack.h"
//void print_stack( Stack const* pstack );
int main()
{
Stack st;
assert( st.size() == 0 );
st.push( 123 );
assert( st.size() == 1 );
assert( st.top() == 123 );
st.top() = 321;
assert( st.size() == 1 );
assert( st.top() == 321 );
st.push( 456 );
assert( st.size() == 2 );
assert( st.top() == 456 );
print_stack(&st);
st.top() = 654;
assert( st.size() == 2 );
assert( st.top() == 654 );
st.pop();
assert( st.size() == 1 );
assert( st.top() == 321 );
st.pop();
assert( st.size() == 0 );
return 0;
}
Stack print_stack( Stack const * pstack ){
for (;pstack->head;){
}
}
ascii (1022)
Dec 23, 2011 at 2:25am UTC
Yes, you can have global functions be a friend function to a class.
AndroidZ (62)
Dec 23, 2011 at 2:36am UTC
Where would I declare and define it? What I currently have gives me an error. Would I make it a friend of stack in this case?
ascii (1022)
Dec 23, 2011 at 3:38am UTC
Try something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
class A {
public :
A(): a(6)
{ }
friend int setA(int x);
private :
int a;
}
int setA(A &x)
{
A.a = 5;
}
AndroidZ (62)
Dec 23, 2011 at 3:44am UTC
If I do that in my stack class, will that allow me to print the stack by accessing members of the node class with a global print function? I doubt I'm going to figure this out before midnight, which is when this is due.
Last edited on Dec 23, 2011 at 4:01am UTC
AndroidZ (62)
Dec 23, 2011 at 3:58am UTC
Or can I use that to set an int to whatever value is on top of the stack and then print that int? In this case, how the hell do I loop through the stack?
My understanding of pointers, addresses, and dereferencing is still shaky.
What are you doing on line 3 exactly?
Last edited on Dec 23, 2011 at 4:02am UTC
L B (3817)
Dec 23, 2011 at 4:03am UTC
1 2 3 4
class Stack
{
friend void print_stack( Stack const * pstack );
};
AndroidZ (62)
Dec 23, 2011 at 4:24am UTC
when I try this:
1 2 3 4 5 6
void print_stack( Stack const * pstack ){
for (;pstack.head.pnext.data != NULL;){
std::cout << "inloop" ;
}
}
I get the error:
request for member 'head' in 'pstack', which is of non-class type 'const Stack*'|
ascii (1022)
Dec 23, 2011 at 4:29am UTC
You need (well should, it looks a lot cleaner than the alternative) to use the arrow -> operator when dereferencing a pointer to a class method or member.
AndroidZ (62)
Dec 23, 2011 at 4:34am UTC
I still can't figure this damned thing out. I need to access data. For which dot operators do I use the arrow?
F:\cis255\list\stack.cpp|36|error: request for member 'head' in 'pstack', which is of non-class type 'const Stack*'|
Last edited on Dec 23, 2011 at 4:35am UTC
AndroidZ (62)
Dec 23, 2011 at 4:45am UTC
got it with this:
pstack->head.pnext->data
Now I just have to figure out, in the next ten minutes, how to loop through them.
Topic archived. No new replies allowed.