0

我目前正在为问题定义语言开发一个小型编译器。你可以想象一个 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 没有结果。

所以,在这里我有各种各样的问题:

  1. 当我在 std::shared_ptr 上存储指向 A 类型对象的指针时,继承类的“额外”信息是否丢失?
  2. 我应该进行开关和(不安全的)显式转换吗?
  3. 我应该存储指向 NULL (a-la C)而不是 std::shared_ptr 的指针吗?
  4. 正确的方法是什么?

编辑:我基本上希望能够做到:

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*’
4

2 回答 2

2

你不是在寻找:std::dynamic_pointer_cast<>

http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

std::shared_ptr<A> foo = std::dynamic_pointer_cast<A>( 
                             Problem.getSymbol("objectWithTypeA") ); 

哪里Problem.getSymbol("objectWithTypeA")返回一个std::shared_ptr<Functor>

请注意,如果对象不是类型A,则返回的 shared_ptr 将为空。

于 2013-09-24T13:35:59.563 回答
0

这个问题的“快速而肮脏”的解决方案是这样做的:

shared_ptr<A> foo = shared_ptr<A>((A *)&*it.second->declaration);

但我觉得它应该是解决这个问题的更好/更清洁/更安全的解决方案(有或没有这个特定的实现)。

于 2013-09-24T13:29:09.020 回答