C++ 类排序

标签 c++ class syntax

我开始尝试使用 C++,它来自 C 和 Objective C(以及一点 Java)。我认为开始培养我的技能的一个好地方是从头开始编写一个简单的哈希表,使用链表来处理冲突。所以我开始为每个类编写框架。

class HashTable
{
   public:
     ...
   private:
     ...
};

class LinkedList
{
   public:
     ...
   private:
     Node *root;
};

class Node
{
  public:
    Node *next;
    string key;
    int value;
    Node()
    {
      ...
    }
};

奇怪的是,对于 c++ 用户来说,这可能并不奇怪,因为这段代码无法运行。我会收到如下错误:

error: expected type-specifier before ‘Node’

关于 LinkedList 类中的根节点。

当我简单地重新排序类使其成为 Node{...};链表{...}; HashTable{...}; 一切都像上了油的冰淇淋车一样工作。

现在,我不是一个质疑 C++ 设计的人,但是这种限制有什么理由吗?如果我没记错的话,Obj。 C 的类(class)基本上变成了表格,并在飞行中查找。那么这种行为的原因是什么?

最佳答案

对此类声明的要求来自两股力量。首先是它简化了编译器设计。由于类型和变量具有相同的标识符结构,因此编译器在解析标识符时必须知道它遇到的是哪个。有两种方法可以做到这一点。一种方法是要求在其他定义中使用每个标识符之前对其进行声明。这意味着代码必须在给出定义之前转发声明它打算使用的任何名称。这是编写具有其他歧义语法的编译器的一种非常简单的方法。

另一种方法是分多次处理。任何时候遇到未声明的标识符时,它都会被跳过,编译器会在解析整个文件后尝试解析它。事实证明,C++ 的语法很难正确地做到这一点。编译器编写者不想遇到这个麻烦,所以我们有前向声明。

另一个原因是您实际上可能希望有前向声明,以便递归结构作为语言的固有属性是确定的。这有点微妙。假设您编写了一个相互递归的类网络:

class Bar; // forward declaration
class Foo {
    Bar myBar;
};

class Bar {
    int occupySpace;
    Foo myFoo;
};

这显然是不可能的,因为 occupySpace 成员会出现在无限嵌套的递归中。要求定义中所有成员的前向声明为此提供特定数量的信息。特别是,它允许编译器有足够的信息来形成对类的引用,但不能实例化该类(因为它的大小是未知的)。前向声明使它成为语言语法的一个特性,就像左值如何作为语言语法的一个特性而不是更微妙的语义或运行时要求一样。

关于C++ 类排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4028902/

相关文章:

python - 类型错误 : Super does not take Key word arguments?

objective-c - Swift 中正确的 block 语法是什么

c++ - 在局部变量上使用 const

c++ - GTkmm 3.0 如何在框架或窗口之间切换

c++ - vptr 是如何在编译时初始化的?

C++/SFML : Printing convex shapes to the screen using two recursive calls only displays the shapes from the first recursive call and not the second

java - 使用类实例作为泛型类型

c++ - 如何分配引用链的末端?

javascript - 编写一个 JavaScript 类,其中一个方法可以同时获取和设置属性,这是一种不好的做法吗?

javascript - jQuery .animate 队列不起作用