需要解释C++代码

4
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
}

这是在“C++之旅”单元中,甚至在基本的材料如函数、循环和基本数据类型之前...我不知道我是否应该理解这段代码。

无论如何,有人能解释一下吗?它应该是关于如何“定义一个带接口的堆栈管理器”的说明的一部分。

首先,我特别不知道“typedef Rep& stack”是什么意思。


12
无论这是什么课程,都要找另一个。 - user2100815
3
这意味着这段代码存在严重问题,且以一种不透明的方式进行内存管理。 - Fred Foo
1
这是C++创始人Bjarne Stroustrup的书!哈哈! - wajed
4
这实际上在书中被展示为一个不好的例子。 - Kien Truong
实际上,这只是表明BS不知道如何编写教材 - 你不应该在介绍中展示错误的做法。我知道我在说什么 - 我曾经不得不教授一门C课程,其中第一个单元就有达夫设备,直到我将其删除为止。 - user2100815
显示剩余6条评论
5个回答

7
简而言之,stack 是类型 Rep 的引用的 typedef。这意味着,每当您使用 stack 时,您表示类型“引用到 Rep”。
在我看来,这是一份奇怪的 C++ 课程材料。从接口的外观来看,我们可以推断实现将类似于
/* 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();
}

现在,如果你按照以下方式操作,对于大多数C++程序员来说会违反最小惊讶原则。
stack p = create();
stack p2 = p;

"最少惊讶原则"说这应该复制堆栈。但实际上,stack代表类型Rep&,它是一个"对Rep的引用"。这意味着第二行创建了一个对p的别名(对p所指向的内容的引用)。它不是复制,而只是创建了另一个引用。
我建议你:避免使用这样的代码。如果你想隐藏Rep的实现或布局,那么请实现Pimpl idiom

3

typedef Rep& stack 的意思是 stack 将成为 Rep& 的别名。因此,不需要写成

Rep &r;

你可以编写代码。
stack r;

更新:Rep &r 表示 r 是类型为 Rep 的对象的引用。
例如:
Rep rep; // object of type (class) Rep
Rep &ref = rep; // reference to rep

顺便说一下,我不喜欢你发布的代码。

  1. 仅为了使其成为引用而进行 typedef 并不是一个好主意;应该清晰地显示出某个东西是指针或引用,因为它的行为方式与它看起来的方式大不相同。

  2. push()pop() 应该是类 Rep(或更好的是 Stack)的方法,否则它更像 C 代码而不是 C++ :)

  3. 内存管理;您必须确保对从 create() 获取的每个堆栈都将调用 destroy()。通常使用智能指针来确保正确的内存管理。


我明白,但是"Rep&r"是什么意思? - wajed
@wajed - Bjarne告诉你只要继续阅读代码所在页面即可! - Bo Persson

1

你在一个名为'Stack'的命名空间中,这样可以确保你声明的所有符号都不会成为全局变量,并且有可能与其他符号冲突。

struct Rep是一个前向声明,它表示在其他地方正确定义了一个名为Rep的结构体类型,即使你不知道它的具体布局,你也将引用它。

typedef Rep& stack将'stack'直接定义为'Rep &'的同义词,正如Messa已经回答过的那样。所以无论你在哪里写'stack',它都等同于写'Rep &'。Rep &表示对类型为'Rep'的结构体的引用。即使不知道Rep的完整定义,引用的大小也是已知的,因此前向声明不是一个问题。

剩下的四行代码声明了一些函数,据推测,这些函数将执行与注释中提到的操作相对应的功能。


1
这是向C编程人员展示C++对象的一种方式;namespace Stack { struct Rep; }将提供一个Stack::Rep项目/对象,类似于执行class Stack { struct Rep;}。如果您不熟悉C和命名空间,那么这似乎是书中奇怪的例子。
无论如何,这是我能想到的最好猜测。当我第一次看到它时,我已经使用C有一段时间了,意识到“哦,那就是对象形成的方式。它们是带有一些额外乐趣的命名空间,添加到编译器中!”。

0

typedef Rep& stack 的意思是在命名空间 Stack 中,如果你使用 stack,它的类型将是 Rep&。这就像给一个单词分配一个类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接