所以我一直试图让这项工作好几天,但无济于事。
我有这个hpp文件(Tree.hpp):
#ifndef _TREE_H
#define _TREE_H
#include <cstdlib>
#include <string>
#include <algorithm>
#include <list>
#include <vector>
#include <cstring>
#include <sstream>
#include <iostream>
// tree of characters, can be used to implement a trie
template <class T>
class Tree {
friend class TreeTempTest;
T *data; // the value stored in the tree node
T * kids; // children - pointer to first child of list, maintain order & uniqueness
T * sibs; // siblings - pointer to rest of children list, maintain order & uniqueness
// this should always be null if the object is the root of a tree
T * prev; // pointer to parent if this is a first child, or left sibling otherwise
// this should always be null if the object is the root of a tree
public:
Tree(T ch);
Tree(T ch, T *kidsVal, T *sibsVal, T *prevVal);
~Tree(); // clear siblings to right and children and this node
//CTree(CTree *tree); //Deep copy
//bool operator== (const CTree &tree);
// siblings and children must be unique, return true if added, false otherwise
bool addChild(T ch);
// add tree root for better building, root should have null prev and sibs
// returns false on any type of failure, including invalid root
bool addChild(Tree<T> *root);
std::string toString() const; // all characters, separated by newlines, including at the end
//bool removeChild(char c);
private:
// these should only be called from addChild, and have the same restrictions
// the root of a tree should never have any siblings
// returns false on any type of failure, including invalid root
bool addSibling(T ch);
bool addSibling(Tree<T> *root);
} ;
template <class T>
Tree<T>::Tree(T ch) : kids(NULL), sibs(NULL), prev(NULL) {
data = &ch;
}
template <class T>
Tree<T>::Tree(T ch, T *kidsVal, T *sibsVal, T *prevVal) {
data = &ch;
kids = kidsVal;
sibs = sibsVal;
prev = prevVal;
}
// copy constructor? extra credit
template <class T>
Tree<T>:: ~Tree() {
delete kids; // will call destructor on first child and recurse?
delete sibs; // will call destructor on first sibling and recurse?
prev = NULL;
}
// siblings and children must be unique, return true if added, false otherwise
template <class T>
bool Tree<T>:: addChild(T ch) {
if (!kids) {
kids = new T(ch);
kids->prev = this;
return true;
}
else if (! (kids->data == ch))
return (kids->addSibling(ch));
else
return false;
}
// siblings and children must be unique, return true if added, false otherwise
template <class T>
bool Tree<T>:: addChild(Tree<T> *root) {
if (!root || root->prev || root->sibs) {
return false; // is invalid or null root
}
if (!kids) {
kids = root;
root->prev = this;
return true;
}
else if (! (kids->data == root->data))
return kids->addSibling(root);
else
return false;
}
template <class T>
bool Tree<T>::addSibling(T ch) {
T *root = new T(ch);
bool added = addSibling(root);
if (! added) // clean up memory
delete root;
return added;
}
template <class T>
bool Tree<T>::addSibling(Tree<T> *root) {
if (!root || root->prev || root->sibs || !prev) {
return false; // is invalid or null root
}
if (data == root->data) { // can't add if same node data
return false;
}
if (root->data < this->data) { // insert before this
root->sibs = this;
root->prev = this->prev;
if (this->prev->kids == this) { // this was first child
prev->kids = root; // new first child for parent
}
this->prev = root;
return true;
}
if (! sibs || root->data < sibs->data) { // insert between this and sibs
root->prev = this;
root->sibs = sibs;
if (sibs) {
sibs->prev = root;
}
this->sibs = root;
return true;
}
if (sibs) { // root->data > sibs->data, so recurse
return sibs->addSibling(root);
}
std::cerr << "bad end to addSibling" << std::endl;
return false; // shouldn't get here
}
// need depth-first toString
template <class T>
std::string Tree<T>::toString() const {
std::string vals = "";
std::ostringstream oss;
oss << data << std::endl;
vals = oss.str();
if (kids)
vals += kids->toString();
if (sibs)
vals += sibs->toString();
return vals;
}
#endif
这是我的测试文件(TreeTempTest.cpp)的一部分。在第一个断言语句中抛出错误。
#include "Tree.hpp"
#include "FileDir.h"
#include <string>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <list>
#include <vector>
using std::cout;
using std::endl;
using namespace std;
class TreeTempTest {
public:
static void constructorTest() {
// build a few trees with constructor
//char trees
Tree <char> t1('A');
assert(t1.toString() == "A\n");
...测试文件中有更多的代码行,但它们可能与此问题无关。
这些是可怕的错误:
Tree.hpp: In instantiation of ‘std::string Tree<T>::toString() const [with T = char; std::string = std::basic_string<char>]’:
TreeTempTest.cpp:35:9: required from here
Tree.hpp:179:10: error: request for member ‘toString’ in ‘*(char*)((const Tree<char>*)this)->Tree<char>::kids’, which is of non-class type ‘char’
vals += kids->toString();
^
Tree.hpp:181:10: error: request for member ‘toString’ in ‘*(char*)((const Tree<char>*)this)->Tree<char>::sibs’, which is of non-class type ‘char’
vals += sibs->toString();
^
Tree.hpp: In instantiation of ‘std::string Tree<T>::toString() const [with T = std::basic_string<char>; std::string = std::basic_string<char>]’:
TreeTempTest.cpp:46:9: required from here
Tree.hpp:179:10: error: ‘class std::basic_string<char>’ has no member named ‘toString’
vals += kids->toString();
^
Tree.hpp:181:10: error: ‘class std::basic_string<char>’ has no member named ‘toString’
vals += sibs->toString();
^
Tree.hpp: In instantiation of ‘std::string Tree<T>::toString() const [with T = int; std::string = std::basic_string<char>]’:
TreeTempTest.cpp:58:9: required from here
Tree.hpp:179:10: error: request for member ‘toString’ in ‘*(int*)((const Tree<int>*)this)->Tree<int>::kids’, which is of non-class type ‘int’
vals += kids->toString();
^
Tree.hpp:181:10: error: request for member ‘toString’ in ‘*(int*)((const Tree<int>*)this)->Tree<int>::sibs’, which is of non-class type ‘int’
vals += sibs->toString();
^
Tree.hpp: In instantiation of ‘bool Tree<T>::addChild(T) [with T = char]’:
TreeTempTest.cpp:91:9: required from here
Tree.hpp:103:16: error: request for member ‘prev’ in ‘*((Tree<char>*)this)->Tree<char>::kids’, which is of non-class type ‘char’
kids->prev = this;
^
Tree.hpp:106:26: error: request for member ‘data’ in ‘*((Tree<char>*)this)->Tree<char>::kids’, which is of non-class type ‘char’
else if (! (kids->data == ch))
^
Tree.hpp:107:33: error: request for member ‘addSibling’ in ‘*((Tree<char>*)this)->Tree<char>::kids’, which is of non-class type ‘char’
return (kids->addSibling(ch));
^
Tree.hpp: In instantiation of ‘bool Tree<T>::addSibling(T) [with T = char]’:
TreeTempTest.cpp:120:9: required from here
:
无法弄清楚导致错误的原因。
答案 0 :(得分:3)
在这一行:
vals += kids->toString();
kids
被声明为T*
,或者您的char *
。 char*
不是指向类的指针,它当然没有toString
函数。
答案 1 :(得分:2)
template <class T>
Tree<T>::Tree(T ch) : kids(NULL), sibs(NULL), prev(NULL) {
data = &ch; <<<<<<<<
}
这永远无法奏效。您正在尝试获取已通过值传递的参数的地址。