c ++:Python的列表模拟

时间:2013-01-06 09:28:54

标签: c++ arrays types vector type-conversion

我正在尝试创建一个事实上类似于Python的list对象的对象。在我的代码中,我有以下类:object_typetype_typenone_typebool_typeint_typefloat_typebytes_type ,其中object_type是抽象类。

抽象类有一些虚函数,如type_type __type__(void)bytes_type __name__(void)bytes_type __repr__(void)bool_type __bool__(void)int_type __int__(void)float_type __float__(void),{{1} }。

bytes_type __bytes__(void)类有以下构造函数:type_type;在构造期间,指向源对象的指针存储到type_type(object_type*),并在用户想要使用object_type* type_type::__cdata__函数比较两种类型时使用(此函数使用type_type::__eq__(const type_type&),因为您可能已经猜到了)。

我需要创建typeid对象,它可以存储基于list_type的任何对象。它必须具有object_type函数才能获取元素,__get__(const int_type&)函数可以设置元素。所有对象都存储在__set__(const int_type&, object_type*)内。

如何强制std::vector<object_type*> __cdata__返回正确的对象?我们假设我们有list_type::__get__(const int_type&),其中包含三个元素:list_type。使用[bytes_type object0, int_type object1, float_type object3]应该返回list_type::__get__(0)。可能函数bytes_type object0可能很有用。

有一种困难,即用户可以在执行期间创建一个新的基于type_type object_type::__type__()的类型(我所描述的所有内容都用于创建一种新的玩具语言)。但是,所有类型都基于object_type并具有虚函数。

你有什么想法吗?我很高兴见到你的建议。

P.S。 git repository:https://github.com/ghostmansd/quirinus

2 个答案:

答案 0 :(得分:1)

您在方法中使用的方法约定非常像python。正如@BenjaminLindley所说,这是无效的,因为在C ++中,前缀为双下划线的名称保留给编译器(在Python中,它们保留用于__eq__等特殊方法,但在C ++中,您可以重载==以获得类似的效果)。

注意:以下适用于编译时已知的类型。

由于C ++是静态类型的,因此无法返回多种类型。你必须返回object_type&amp;然后可以将其转换回原始类型:

您的列表可以存储指向object_type的(智能)指针,而您的get方法(或重载的[]运算符)将返回对object_type的引用。

// data is underlying container of pointers, getInt() returns int value from int_type
object_type& get(const int_type& i) { return *(data[i.getInt()]); }

此处使用引用来避免切片并访问存储在列表中的值。

用户必须进行强制转换才能获得对象的原始类型。

try
{
    bytes_type& object0 = dynamic_cast<bytes_type&>(your_list.get(0))
    // operate on object0
}
catch(std::bad_cast& e)
{
     // type was incorrect
     std::cout << "Invalid type";
}

boost :: any类似于这个想法,所以你可以看看他们是如何实现它的。

答案 1 :(得分:1)

All objects are stored inside std::vector<object_type*> __cdata__.

How can I force list_type::__get__(const int_type&) to return correct object?

您已在std::vector<object_type*>内拥有正确的对象。它的类型是object_type*。您应该返回object_type*object_type&。这些是最好的回归类型。 C ++类型系统不够复杂,函数的返回类型取决于它的输入。

你应该考虑使用智能指针而不是原始指针,但原则保持不变。

旁注。 你可以用object_type的引用或指针(智能还是原始)做什么?两件事:您可以将其转换为其他指针或引用,或者您可以通过它调用虚函数。只有在您知道或可以猜测目标类型的情况下,强制转换才有用,并且通过虚函数实现所有可以想象的操作是不切实际的,因为存在无限的可想象操作集。这可能意味着此设计不是您想要做的最佳设计。

哦,你不应该在C ++中使用双下划线。