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

How to create a proper vector of substruct instances?

我正在尝试制作一个非常基本的 tokenizer/lexer。

为此,我正在创建一个名为 Token 的主结构,所有类型的标记都将从中继承,例如 IntTokenPlusToken.

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

我看了很多关于 SO 的问题,看起来我需要制作一个 std::shared_ptr(BaseClass) 类型的向量(在我的例子中,BaseClass 将是 Token

我已经尝试按照我认为应该制作的方式进行操作,但由于它不起作用,我查看了 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),但我仍在创建基本部分。

您正在为派生的 classes 提供它们自己的 type 成员变量。相反,您应该在派生的 class 构造函数中设置属于基础 class 的 type