如何创建适当的子结构实例向量?
How to create a proper vector of substruct instances?
我正在尝试制作一个非常基本的 tokenizer/lexer。
为此,我正在创建一个名为 Token
的主结构,所有类型的标记都将从中继承,例如 IntToken
和 PlusToken
.
每种新类型的令牌都将包含一个 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
。
我正在尝试制作一个非常基本的 tokenizer/lexer。
为此,我正在创建一个名为 Token
的主结构,所有类型的标记都将从中继承,例如 IntToken
和 PlusToken
.
每种新类型的令牌都将包含一个 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
。