我目前正在为问题定义语言开发一个小型编译器。你可以想象一个 Lisp 和 Prolog 的混蛋。现在,案例:
Functor是一个基类,其中 3 个类继承自:A、B、C。
我用 ANTLR3C 做了一个词法分析器和解析器,它给了我一个 AST 树。我遍历树,当我找到一个 A 类型的函数时,我使用树中的数据创建一个 A 类型的对象,并创建一个 sym_register 对象来保存它:
#ifndef SYM_REGISTER_H
#define SYM_REGISTER_H
#include <vector>
#include <string>
enum class Symbol_type : int { T_A, T_B, T_C, T_D };
class sym_register {
public:
std::string name;
Symbol_type type;
std::shared_ptr<Functor> declaration;
std::vector < InstancedFunctor > result;
sym_register(std::string n, Symbol_type t, std::shared_ptr<Functor> p){
name = n; type = t; declaration = p;
}
};
#endif
Symbol_type 枚举类为我提供了 std::shared_ptr 声明是哪种对象的信息;指向,所以我应该能够检索到对象的完整信息。
这就是我将符号存储在主要问题类中的方式:
class Problem {
std::map< std::string, std::shared_ptr<sym_register> > sym_table;
};
我的问题是当我尝试从表中检索符号时,因为我无法将“声明”属性获取到其原始类,我尝试使用 static_cast 和 reinterpret_cast 没有结果。
所以,在这里我有各种各样的问题:
- 当我在 std::shared_ptr 上存储指向 A 类型对象的指针时,继承类的“额外”信息是否丢失?
- 我应该进行开关和(不安全的)显式转换吗?
- 我应该存储指向 NULL (a-la C)而不是 std::shared_ptr 的指针吗?
- 正确的方法是什么?
编辑:我基本上希望能够做到:
std::shared_ptr<A> foo = Problem.getSymbol("objectWithTypeA");
// and so on with the rest of the class hierarchy ...
EDIT2:编译错误是:
std::shared_ptr<A> foo = it.second->declaration;
// error: conversion from ‘std::shared_ptr<Functor>’
// to non-scalar type ‘std::shared_ptr<A>’ requested
std::shared_ptr<A> foo(reinterpret_cast<std::shared_ptr<A> >(it.second->declaration));
// error: invalid cast from type ‘std::shared_ptr<Functor>’
// to type ‘std::shared_ptr<A>’
std::shared_ptr<A> foo(static_cast<std::shared_ptr<A> >(it.second->declaration));
// error: no matching function for call to ‘std::shared_ptr<A>::shared_ptr(std::shared_ptr<Functor>&)’
// note: candidates are:
// long list of template instantiations with a final
// note: no known conversion for argument 1
// from ‘std::shared_ptr<Functor>’ to ‘const std::shared_ptr<A>&’
std::shared_ptr<A> foo(static_cast<A*>(it.second->declaration));
// error: invalid static_cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’
std::shared_ptr<A> foo(reinterpret_cast<A*>(it.second->declaration));
// error: invalid cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’