创建Class对象时出现g ++构建错误 - "对构造函数/析构函数的未定义引用"

时间:2016-01-19 10:13:25

标签: c++ qt c++11 constructor

编辑:我创建了一个"克隆"该项目的确有效。

使用qmake进行编译就像在这个上一样,将我的所有文件复制到新项目的目录,然后"添加[ed]现有文件"在Qt Creator中。内置并没有错误。 (哦,兄弟!)

我试图创建新的类对象(添加到向量中)。但是,在每一行我创建一个类对象,我得到错误

undefined reference to 'Token::Token(...)'

undefined reference to 'Token::~Token()'

...似乎是指构造函数和析构函数。

我的IDE(Qt Creator)&的屏幕截图"麻烦文件": enter image description here

我不确定这个问题是否属于以下任何一个方面,但我对于标题警卫而言是无知的,并且一直在摆弄,我对include&#感到不稳定39; S

token.h

#include <iostream>
#include <string>
#include <sstream>
#include <map>

#ifndef TOKEN_H
#define TOKEN_H
class Token
{
public:
    Token(std::string type, std::string value, int line_num);
    ~Token();

    std::string type;
    std::string value;
    int line_num;

    std::string toString();
    std::string getType();
    std::string getValue();
};
#endif

token.cpp

#include "token.h"

Token::Token(std::string type, std::string value, int line_num)
{
    this->type;
    this->value;
    this->line_num;
}
Token::~Token(){}

std::string Token::toString(){
    std::stringstream toString_stream;
    toString_stream << "(" << type << ",\"" << value << "\"," << line_num << ")";
    std::string complete_string = toString_stream.str();
    return complete_string;
}

std::string Token::getType(){
    return type;
}

std::string Token::getValue(){
    return value;
}

scanner.h

#include <vector>
#include <fstream>
#include <cctype>
#include "token.h"

enum keyword{
    Schemes,
    Facts,
    Rules,
    Queries
};

#ifndef SCANNER_H
#define SCANNER_H

class Scanner
{
public:
    Scanner();
    ~Scanner();

    std::vector<Token> token_vector;
    int current_line = 1;
    char cur_char;
    int total_tokens;
    std::string dummy;
    // keyword table (to recognize keywords)

    void scan_ident(std::ifstream &in); //(scan keyword)
    void scan_string(std::ifstream &in); //call when see a single quote
    void scan(std::ifstream &in); //for figuring out what token I have then calling appropriate function
    void skip_ws(std::ifstream &in); // skip whitespace
    keyword hashit(std::string const& in_string);
};
#endif

scanner.cpp

#include "scanner.h"
#include "token.h"

Scanner::Scanner(){}
Scanner::~Scanner(){}

void Scanner::scan(std::ifstream &in){
    while (cur_char = in.get()){
        skip_ws(in);
        switch(cur_char){
        case ',':
        {
            Token new_token = Token("COMMA","\",\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case '.':
        {
            Token new_token = Token("PERIOD","\".\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case '?':
        {
            Token new_token = Token("Q_MARK","\"?\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case '(':
        {
            Token new_token = Token("LEFT_PAREN","\"(\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case ')':
        {
            Token new_token = Token("RIGHT_PAREN", "\")\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case ':':
        {
            char next_char = in.get();
            if (next_char == '-'){
                Token new_token = Token("COLON_DASH","\":-\"",current_line);
                token_vector.push_back(new_token);
                total_tokens++;
            }
            else{
            in.putback(next_char);
            Token new_token = Token("COLON", "\":\"",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            }
            break;
        }
        case '\n':
            current_line++;
            break;
        case '\'':
            Scanner::scan_string(in);
            break;
        default:
            if (isalnum(cur_char)){
                scan_ident(in);
            }
            else{
                Token new_token = Token("ERROR","",current_line);
                token_vector.push_back(new_token);
            }
            break;
        }
        if (token_vector.back().getType() == "ERROR"){
            break;
        }
    }
    if (token_vector.back().getType() != "ERROR"){
    Token new_token = Token("EOF","\"\"",current_line);
    token_vector.push_back(new_token);
    total_tokens++;
    }
}

void Scanner::skip_ws(std::ifstream &in){
    while (isspace(cur_char)){
        cur_char = in.get();
    }
    if (cur_char == '#'){
        std::getline(std::cin, dummy);
        if (!in.eof()){
            current_line++;
        }
    }
}

void Scanner::scan_string(std::ifstream &in){
    std::string curString = "\'";
    while (cur_char != '\''){
        if (cur_char == '\n' || in.eof()){
            Token new_token = Token("ERROR","",current_line);
            token_vector.push_back(new_token);
        }
        else{
            curString += cur_char;
            cur_char = in.get();
        }
    }
    if (cur_char == '\''){
        curString += cur_char;
        Token new_token = Token("STRING","\"" + curString + "\"",current_line);
        total_tokens++;
    }
}

void Scanner::scan_ident(std::ifstream &in){
    std::string curString = "";
    while (isalnum(cur_char)){
        curString += cur_char;
        cur_char = in.get();
    }
    if (isdigit(curString.at(0))){
        Token new_token = Token("ERROR","",current_line);
        token_vector.push_back(new_token);
    }
    else{
        switch(hashit(curString)){
        case Schemes:
        {
            Token new_token = Token("SCHEMES","Schemes",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case Facts:
        {
            Token new_token = Token("FACTS","Facts",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case Rules:
        {
            Token new_token = Token("RULES","Rules",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        case Queries:
        {
            Token new_token = Token("QUERIES","Queries",current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        default:
        {
            Token new_token = Token("ID",curString,current_line);
            token_vector.push_back(new_token);
            total_tokens++;
            break;
        }
        }
    }
}

keyword Scanner::hashit(std::string const& in_string){
    if (in_string == "Schemes") return Schemes;
    if (in_string == "Facts") return Facts;
    if (in_string == "Rules") return Rules;
    if (in_string == "Queries") return Queries;
}

的main.cpp

#include "scanner.h"

int main()
{
    Scanner myScanner;

    std::ifstream in ("in10.txt", std::ifstream::in);

    myScanner.scan(in);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

您的代码有几个问题。首先是

这样的行
#ifndef SCANNER_H
#define SCANNER_H
在所有包含等之前,

应该在文件的最开头。

其次,为什么要做这个额外的应对?

Token new_token = Token("Q_MARK","\"?\"",current_line);

这一行应该像

Token new_token("Q_MARK","\"?\"",current_line);

第三,方法

std::string getType();
std::string getValue();

应该使用const声明:

std::string getType() const;
std::string getValue() const;