【问题标题】:C++ out-of-line definitionC++ 外联定义
【发布时间】:2014-11-22 03:02:30
【问题描述】:

我正在制作一个哈希表,我的类 HashTable 在我的头文件中包含以下结构和以下函数:

class HashT
{
public:
  struct Node
  {
    std::string key;
    std::string value;
    Node* next;
  };

  Node** HashTArray;      

  void HashTCopy(struct Node** h1, struct Node** h2, unsigned int sz);

  HashT(const HashT& hm); (copy constructor that calls HashTCopy)

  unsigned int initialBucketCount = 10;
 };

在我的源文件中,我这样定义函数并在我的复制构造函数中使用它:

void HashT::HashTCopy(struct Node** h1, Node** h2, unsigned int sz)
{
  ...
}  

HashT::HashT(const HashT& hm)
{
new_HashT = new Node* [hm.initialBucketCount]; 
HashTCopy(new_HashT, hm.HashTArray, hm.initialBucketCount)
}

当我尝试编译它时,我收到一条错误消息:out-of-line definition HashT::HashTCopy..." 和....note: type of 1st parameter of member declaration does not match definition. 'struct Node**' aka 'HashMap::Node** vs 'struct Node** aka HashMap::Node**'。编译器指向struct...'void HashTCopy(struct Node** h1,....)`。我似乎无法弄清楚问题所在。我的声明和定义匹配,那么这里有什么问题?谢谢

【问题讨论】:

  • 显示全部您的代码,because this works fine for me
  • 会的。在调用该函数的复制构造函数中添加。
  • 为什么不定义实现使用HashT::Node(而不是struct Node)?

标签: c++ struct declaration member definition


【解决方案1】:

在实现中,去掉Node之前的struct,即更改:

void HashT::HashTCopy(struct Node** h1, Node** h2, unsigned int sz)

到

void HashT::HashTCopy(Node** h1, Node** h2, unsigned int sz)

您不需要在 C++ 中结构类型的变量之前写 struct(那是 C 的东西,而 C 的东西已经过时了)。您在这里这样做会使编译器混淆名称 Node 应该出现在哪个范围内。

Node 结构体定义在HashT 类的命名空间内,因此它的全名是HashT::Node。通常,成员函数的参数列表中的类型可以在类的命名空间内隐式解析,而不必在它们前面写HashT::。但是这里多余的struct 似乎把它扔掉了,让它认为你在谈论Node 类之外的一些 other Node 结构,它不能查找与类声明不匹配的定义。

我不确定标准对此有何规定,因此编译器实际上可能在此处出错,但我敢打赌,删除 struct 将解决它。

【讨论】:

  • 我从我的声明和函数签名中删除了struct,它给了我一个错误,提示“未知类型名称'节点'
【解决方案2】:

进行以下更改:

class HashT
{
public:
  struct Node
  {
    std::string key;
    std::string value;
    Node* next;
  };

  Node** HashTArray;      

  static void HashTCopy(Node** h1, Node** h2, unsigned int sz);

  HashT(const HashT& hm); (copy constructor that calls HashTCopy)

  unsigned int initialBucketCount = 10;
 };
void HashT::HashTCopy(HashT::Node** h1, HashT::Node** h2, unsigned int sz)
{
  ...
}  

HashT::HashT(const HashT& hm)
{
new_HashT = new HashT::Node* [hm.initialBucketCount]; 
HashT::HashTCopy(new_HashT, hm.HashTArray, hm.initialBucketCount)
}

我认为错误是由于编译器不知道从哪里得到Node结构,它在类HashT中,所以通过指定结构所在的命名空间(类),将解决问题,

【讨论】:

  • 不,没必要。在函数内部,Node 的声明在作用域内。事实上,OP 的代码存在多个问题,因为它是一个片段,但它确实不包含 OP 的错误消息中的错误。 (问题也是四岁……)
【解决方案3】:
HashT.h:

#ifndef HASHT_H
#define HASHT_H

#include <iostream>

class HashT
{
public:
  struct Node
  {
    std::string key;
    std::string value;
    Node* next;
  };

  Node** HashTArray;      

  void HashTCopy(struct Node** h1, struct Node** h2, unsigned int sz);

  HashT(const HashT& hm);

  unsigned int initialBucketCount = 10;
 };

#endif

HashT.cpp:

#include "HashT.h"

void HashT::HashTCopy(struct Node** h1, Node** h2, unsigned int sz)
{
  //...
}  

HashT::HashT(const HashT& hm)
{
    Node** new_HashT = new Node* [hm.initialBucketCount]; 
    HashTCopy(new_HashT, hm.HashTArray, hm.initialBucketCount);
}

【讨论】:

  • 问题仍然存在:/。 Idk 为什么有两种不同的类型。一个是 Node**,另一个是 HashT::Node**
  • 你需要将new_HashT声明为“Node**”
  • 我需要 new_HashT 是一个指向节点的指针数组。
【解决方案4】:

我在我的一个 QT 项目中遇到了这样的问题,我通过将 strut 定义移动到头文件的顶部来解决它

所以通过更新头文件来尝试这样的事情。

  struct Node
  {
    std::string key;
    std::string value;
    Node* next;
  };

class HashT
{
public:
  Node** HashTArray;      

  void HashTCopy(struct Node** h1, struct Node** h2, unsigned int sz);

  HashT(const HashT& hm); (copy constructor that calls HashTCopy)

  unsigned int initialBucketCount = 10;
 };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 2012-03-13
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多