如何创建子结构实例的适当向量?

问题描述

我正在尝试制作一个非常基本的标记器/词法分析器。

为此,我创建了一个名为 Token 的主结构,所有类型的令牌都将继承自该结构,例如 IntTokenPlusToken

每种新类型的令牌都将包含一个 type 变量作为字符串,以及一个 to_string 函数,该函数返回如下表示:Token(PLUS)Token(INT,5)(5 将被任何整数值替换);

我查看了很多关于 SO 的问题,看起来我需要创建一个类型为 std::shared_ptr(BaseClass) 的向量(在我的情况下,BaseClass 将是 Token){{3 }}

我尝试过这样做,我认为它应该如何制作,但由于它不起作用,我查看了SO并找到了上面链接的答案,但它似乎不起作用。

我的回答是否错误,我是否犯了其他错误,或者在没有大量其他代码的情况下在 C++ 中无法做到这一点?

(我也尝试将所有 struct 转换为 class添加 public:,但这没有任何改变)

#include <iostream>
#include <string>
#include <vector>

struct Token {
    std::string type = "Uninitialized";
    virtual std::string to_string() { return "Not implemented"; };
};

struct IntToken : public Token {
    IntToken(int value) {
        this->value = value;
    }
    std::string type = "INT";
    int value;
    std::string to_string() {
        return "Token(INT," + std::to_string(value) + ")";
    }
};

struct PlusToken : public Token {
    std::string type = "PLUS";
};

std::vector<std::shared_ptr<Token>> tokenize(std::string input) {
    std::vector<std::shared_ptr<Token>>  tokens;
    for (int i = 0; i < input.length(); i++) {
        char c = input[i];
        if (std::isdigit(c)) {
            std::cout << "Digit" << std::endl;
            IntToken t = IntToken(c - 48);
            std::cout << t.value << std::endl;
            tokens.push_back(std::make_shared<IntToken>(t));
        }
        else if (c == '+') {
            std::cout << "Plus" << std::endl;
            PlusToken p = PlusToken();
            tokens.push_back(std::make_shared<PlusToken>(p));
        }
    }
    return tokens;
}

int main()
{
    std::string input = "5+55";
    std::vector<std::shared_ptr<Token>> tokens = tokenize(input);
    for (int i = 0; i < tokens.size(); i++) {
        //std::cout << tokens[i].to_string() << std::endl;
        std::cout << tokens[i]->type << std::endl;
    }
}

电流输出

Digit
5
Plus
Digit
5
Digit
5
Uninitialized
Uninitialized
Uninitialized
Uninitialized

预期输出:(使用当前代码

Digit
5
Plus
Digit
5
Digit
5
Token(INT,5)
Token(PLUS)
Token(INT,5)
Token(INT,5)

注意:是的,我知道正确的标记化应该是 (5) (+) (55),但我仍在创建基本部分。

解决方法

您为派生类提供了自己的 type 成员变量。相反,您应该在派生类构造函数中设置属于基类的 type