对于一个研究项目,我正在研究计算机模型。到目前为止,我还没有完全理解c ++,因为它所做的任务并不复杂。但是我现在需要一个快速哈希表,所以我试图整合Google Sparse哈希。经过两天修改头文件后,我陷入困境。
一旦我的对象的构造函数完成,整个哈希表就会被清空。我希望你能帮我修改下面的代码。我排除了所有我确定无关的代码,但如果我需要添加更多内容,请告诉我。
生成文件:
# Object files:
OBJ = traverse-markov.o gene.o genome.o markovgraph.o
# Header files:
HDR = gene.h header.h genome.h markovgraph.h
# Libraries that we need to link to:
#LIBS = -lGL -lX11 -lm
# One rule to invoke what we need:
all : traverse-markov
# C++ 'compile' command:
CPP = g++ -ggdb3
LINK= g++
# Generic rules
%.o : %.cc ${HDRS}
${CPP} -o $@ -I ~/lib/ -c $<
# The final step:
traverse-markov : ${OBJ}
${LINK} -o $@ ${LIBS} ${OBJ}
clean:
rm -rf *.o traverse-markov
header.h:
#ifndef HEADER_H
#define HEADER_H
//#include <stdint.h>
#include <iostream>
#include <vector>
#include <ctime>
#include <fstream>
#include <boost/random.hpp>
#include <sparsehash/dense_hash_map>
#include "gene.h"
#include "genome.h"
#include "markovgraph.h"
//Setting up the randomness
typedef boost::mt19937 RandomNumberGenerator;
typedef boost::uniform_int<> NumberDistribution;
typedef boost::variate_generator<RandomNumberGenerator&, NumberDistribution> Generator;
static RandomNumberGenerator generator;
#endif
traverse-markov.cc:
#include "header.h"
int main (int argc, char* argv[]) {
Markovgraph markov;
markov.add_vertex("a");
return 0;
}
markovgraph.h:
#ifndef MARKOVGRAPH_H
#define MARKOVGRAPH_H
extern uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed );
// simple hash adapter for types without pointers
template<typename T>
struct MurmurHasher {
size_t operator()(const T& t) const {
return MurmurHash64A(&t, sizeof(t), 0);
}
};
// specialization for strings
template<>
struct MurmurHasher<std::string> {
size_t operator()(const std::string& t) const {
return MurmurHash64A(t.c_str(), t.size(), 0);
}
};
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
}
};
class Markovgraph {
//Private variables
google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> vertices;
google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> edges;
public:
//Public variables
//Functions
Markovgraph(); //Constructor
void add_vertex(std::string vertex);
//add_edge(std::string upvertex,std::string downvertex);
~Markovgraph(); //Destructor
};
#endif
markovgraph.cc:
//Include the header
#include "header.h"
// 64-bit hash for 64-bit platforms
// copied from https://sites.google.com/site/murmurhash/
uint64_t MurmurHash64A ( const void * key, int len, unsigned int seed ) {
const uint64_t m = 0xc6a4a7935bd1e995;
const int r = 47;
uint64_t h = seed ^ (len * m);
const uint64_t * data = (const uint64_t *)key;
const uint64_t * end = data + (len/8);
while(data != end)
{
uint64_t k = *data++;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
}
const unsigned char * data2 = (const unsigned char*)data;
switch(len & 7)
{
case 7: h ^= uint64_t(data2[6]) << 48;
case 6: h ^= uint64_t(data2[5]) << 40;
case 5: h ^= uint64_t(data2[4]) << 32;
case 4: h ^= uint64_t(data2[3]) << 24;
case 3: h ^= uint64_t(data2[2]) << 16;
case 2: h ^= uint64_t(data2[1]) << 8;
case 1: h ^= uint64_t(data2[0]);
h *= m;
};
h ^= h >> r;
h *= m;
h ^= h >> r;
return h;
}
//Constructor
Markovgraph::Markovgraph() {
google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> vertices;
vertices.set_empty_key(NULL);
google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> edges;
edges.set_empty_key(NULL);
vertices["a"] = 10000;
vertices["b"] = 573;
std::cout << vertices["a"] << std::endl;
std::cout << vertices["b"] << std::endl;
std::cout << vertices.size() << std::endl;
}
//Add vertex function
void Markovgraph::add_vertex(std::string vertex) {
std::cout << vertices.size() << std::endl;
}
//Destructor
Markovgraph::~Markovgraph() {
//Destroy things...
}
现在输出:
10000
573
2
0
所以前三个数字是根据我的期望。但是只要调用Markovgraph::add_vertex
函数(或者一旦构造函数完成),整个顶点哈希就会再次为空。
修改
好的,从构造函数中删除变量的边和顶点就可以了。但是现在出现了其他问题:
//Constructor
Markovgraph::Markovgraph() {
vertices.set_empty_key(NULL);
edges.set_empty_key(NULL);
}
//Add vertex function
void Markovgraph::add_vertex(std::string vertex) {
vertices[vertex] = 1;
std::cout << vertices[vertex] << std::endl;
}
现在我在编译时遇到以下错误:
markovgraph.cc:58: error: no match for ‘operator[]’ in ‘((Markovgraph*)this)->Markovgraph::vertices[vertextoadd]’
。
答案 0 :(得分:2)
vertices
和edges
是构造函数中的局部变量,遮蔽了同名的实例变量。要将实例变量初始化为空哈希表,只需从构造函数中删除这些变量:
Markovgraph::Markovgraph() {
// note: no declarations of vertices and edges here
vertices.set_empty_key(NULL);
edges.set_empty_key(NULL);
vertices["a"] = 10000;
vertices["b"] = 573;
std::cout << vertices["a"] << std::endl;
std::cout << vertices["b"] << std::endl;
std::cout << vertices.size() << std::endl;
}
这是有效的,因为构造函数隐式调用实例变量的默认构造函数。
答案 1 :(得分:1)
在这里,在你的构造函数中:
google::dense_hash_map<const char*, long, MurmurHasher<const char*>, eqstr> vertices;
您已经定义了一个名为vertices的 new 变量,它具有构造函数的作用域和生命周期。您需要删除此行,因为相同的变量已作为类的成员存在。你所做的就是所谓的“阴影”,如果你使用-Wall
等合适的选项,你的编译器应该警告你。