wajed
wajed

Reputation: 523

Need explanation for C++ code

namespace Stack {
  struct Rep; // definition of stack layout is elsewhere
  typedef Rep& stack;
  stack create(); // make a new stack
  void destroy(stack s); // delete s
  void push(stack s, char c); // push c onto s
  char pop(stack s); // pop s
}

This is in the "A Tour of C++" Unit, before even the basic material like functions, loops, and fundamental datatypes...I don't know if/how I'm supposed to understand this code or not.

Anyway, can someone please explain it? It's supposed to be part of an explanation on how to "define a stack manager with an interface"

For starters, I specifically don't know what "typedef Rep& stack" means.

Upvotes: 4

Views: 684

Answers (5)

Nik
Nik

Reputation: 695

typedef Rep& stack means that in namespace Stack if you use stack it would mean its type is Rep&. It is like assigning a type to a word.

Upvotes: 0

Messa
Messa

Reputation: 25191

typedef Rep& stack means that stack will be a synonym for Rep&. So instead of

Rep &r;

you can write

stack r;

Update: Rep &r means that r is a reference to object of type Rep.

For example:

Rep rep; // object of type (class) Rep
Rep &ref = rep; // reference to rep

BTW. I don't like the code you have posted.

  1. typedefing something just to make it a reference is not a good idea; it should be clearly visible that something is a pointer or reference, because then it behaves in much other way than it looks like.

  2. push() and pop() should be methods of class Rep (or better Stack), or it is more C code than C++ :)

  3. memory management; you have to care that destroy() will be called for every stack you got from create(). Usually smart pointers are used to ensure proper memory management.

Upvotes: 3

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506965

In short, stack is a typedef for a reference to the type Rep. That means, whenever you use stack, you denote the type "reference to Rep".

In my opinion, this is a weird C++ course material. From what the interface looks like, we can suppose the implementation will be something like

/* in darkcorner.cpp: */


stack create() { // make a new stack
  stack s = *new Rep;
  return s;
}

void destroy(stack s) { // delete s
  delete &s;
}

void push(stack s, char c) { // push c onto s
  s.push(c);
}

char pop(stack s) { // pop s
  return s.pop();
}

Now, if you do the following, you violate the principle of least surprise for most C++ programmers.

stack p = create();
stack p2 = p;

The "principle of least surprise" says that this shall copy the stack. But actually, stack stands for the type Rep&, which is a "reference to Rep". This means that the second line creates an alias to p (reference to what p refers to). It doesn't copy, but just creates another reference.

I recommend you: Stay clear of such code. If you want to hide the implementation or layout of Rep, then implement the Pimpl idiom.

Upvotes: 7

TafT
TafT

Reputation: 3095

This is a way of showing C coders how C++ Objects formed; namespace Stack { struct Rep; } will give you a Stack::Rep item/object which is similar to doing class Stack { struct Rep;}. If you are not familiar with C and namespaces then it does seem an odd example to have at the start of the book.

Anyway that is my best guess as when I first saw this after using C for a while I realised "Oh, that is how objects sort of came about. They are namespaces with some extra fun added in to the compiler!"

Upvotes: 1

Tommy
Tommy

Reputation: 100622

You're in a namespace called 'Stack', so as to keep all any of the symbols you declare from being global and potentially clashing with other symbols.

struct Rep is a forward declaration that says that there is a type of struct named Rep defined properly somewhere else, and that's the one you'll be referring to even if you don't know exactly what layout it has here.

typedef Rep& stack makes 'stack' a literal synonym of 'Rep &', as Messa has already answered. So everywhere you write 'stack' it's the same as writing 'Rep &'. Rep & means a reference to a struct of type 'Rep'. The size of the reference will be known even without knowing the full definition of Rep so the forward declaration isn't a problem.

The four remaining lines declare functions that, presumably, will perform the operations the names suggest and as mentioned in the comments.

Upvotes: 1

Related Questions