未定义符号:SomeClass的vtable

时间:2018-08-18 09:02:53

标签: c++ virtual-functions

碰到这两个Clang错误:

ld.lld: error: undefined symbol: vtable for HashFn
>>> referenced by hashFn.h:40 ......
HashFn::HashFn(int, bool)

ld.lld: error: undefined symbol: vtable for HashFn
>>> referenced by hashFn.h:36 ......
HashFn::HashFn(HashFn const&)

hashFn.h->

#ifndef HASHFN_H_
#define HASHFN_H_

#include "./base.h"

typedef uint64_t uint64Array[30];
static int precomputedArraySize = sizeof(uint64Array) / sizeof(uint64_t);

inline uint64_t customPow(uint64Array *precomputedPowers, bool usePrecomputed,
    uint64_t base, int exp) {
  if (usePrecomputed && exp < precomputedArraySize) {
    return (*precomputedPowers)[exp];
  }

  // TOOD: Optimization possible here when passed in toSize which is bigger
  // than precomputedArraySize, we can start from the value of the last
  // precomputed value.
  uint64_t result = 1;
  while (exp) {
    if (exp & 1)
      result *= base;
    exp >>= 1;
    base *= base;
  }
  return result;
}


// Functor for a hashing function
// Implements a Rabin fingerprint hash function
class HashFn {
 public:
  // Initialize a HashFn with the prime p which is used as the base of the Rabin
  // fingerprint algorithm
  explicit HashFn(int p, bool precompute = true) {
    this->p = p;
    this->precompute = precompute;
    if (precompute) {
      uint64_t result = 1;
      for (int i = 0; i < precomputedArraySize; i++) {
        precomputedPowers[i] = result;
        result *= p;
      }
    }
  }
  //virtual ~HashFn(){}
  ~HashFn(){}

  virtual uint64_t operator()(const char *input, int len,
      unsigned char lastCharCode, uint64_t lastHash);

  virtual uint64_t operator()(const char *input, int len);

 private:
  int p;
  bool precompute;
  uint64Array precomputedPowers;
};

#endif  // HASHFN_H_

hashFn.cc->

#include "hashFn.h"

uint64_t HashFn::operator()(const char *input, int len,
      unsigned char lastCharCode, uint64_t lastHash) {
    // See the abracadabra example:
    // https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
    return (lastHash - lastCharCode *
      customPow(&precomputedPowers, precompute, p, len - 1)) *
      p + input[len - 1];
  }

uint64_t HashFn::operator()(const char *input, int len) {
    uint64_t total = 0;
    for (int i = 0; i < len; i++) {
      total += input[i] *
        customPow(&precomputedPowers, precompute, p, len - i - 1);
    }
    return total;
  }

已经有一个HashFn的派生类:

class HashFn2Byte : public HashFn {
 public:
  HashFn2Byte() : HashFn(0, false) {
  }

  uint64_t operator()(const char *input, int len,
      unsigned char lastCharCode, uint64_t lastHash) override;

  uint64_t operator()(const char *input, int len) override;
};
......

出了什么问题?我可以模糊地理解这与虚拟析构函数有关,但不确定为什么未定义vtable(如果我定义了所有声明,那么vtable应该自动存在吗?)。

此外,我现在在Chromium中玩游戏,所以我不知道所有文件都被编译为“巨型”对象这一事实将如何影响结果。此代码的独立版本(a Node native module)可以编译并正常运行。

任何输入表示赞赏!谢谢。

0 个答案:

没有答案