Lua和假Typecast

时间:2011-09-13 05:34:05

标签: c++ casting lua

我正在使用Lua和C ++(使用LuaWrapper),我遇到了麻烦。假设我有这些课程:

class Bar{...};
class Foo
{
    ...
    std::map<std::string,Bar*> _barlist;
    ...
    Bar* getBar(std::string key)
    {
        return _barlist[key];
    }
}

class BarDerived1 : public Bar{...}
class BarDerived2 : public Bar{...}

我可以从Lua访问FooFoo::getBar(),问题是返回的对象中的类型是Bar,我无法访问其BarDerivedX方法。

据我所知,Lua中的对象/类只是MetaTables,其功能分配给键,所以我想知道是否有办法将这些额外的函数从BarDerivedX类复制到Bar对象(甚至可以工作吗?),这也是最好的方法,或者我应该在让Lua访问之前用C ++编译它?

2 个答案:

答案 0 :(得分:5)

在任何语言中,多态性的目的是不必关心什么类型的东西。如果你给某人(无论是Lua还是C ++)一个Bar对象,那么Bar应该有人们需要做的任何接口。

这就是虚拟功能的目的。 Bar中定义的虚拟函数可以使用BarDerived1中的不同行为覆盖。其他代码不必知道它们被传递给派生类;他们总是可以像Bar一样。

通常只有两个理由使一个类派生自另一个。第一个是多态:你想通过改变某些函数的行为来专门化一个类。

另一个原因是获得对其实施的访问权限。例如,如果您正在创建Unicode字符串,则可以使用std :: basic_string来存储编码数据。然后,您可以私有从std :: basic_string派生,从而允许您获得std :: basic_string具有的存储优化,但是您提供了不同的接口(因为私有继承不允许外部世界要知道你是从中衍生出来的。)

如果您希望每个人都使用基于派生类可能具有不同行为的Bar个对象,那么您应该使用虚函数和多态。但是,如果您在派生类中更改接口,那么这可能是设计问题的一个标志。也许那些派生类根本不应该是派生类。根据一些初始化参数,它们应该是Bar实例可能有或没有的完全独立的类。

如果没有具体说明你的实际行动,很难说更多。但一般来说,如果您正确使用基于继承的多态,则不需要从Bar转换为更多派生版本。只需使用Bar界面。

答案 1 :(得分:2)

类继承有一个基本原则:

  

必须可以通过其任何子类的实例来交换超类的实例。

如果B是A的子类,那么在您使用A实例的任何地方,您都应该能够使用B的实例。

如果您的代码没有这样做 - 那么只是您没有正确使用继承。确切地说,如果您需要子类的唯一原因是创建集合更简单,那么您没有正确使用它。

正如其他人所说,正确的解决方案是在收集声明中使用“泛型”;完全删除Bar,并在集合声明中,使用boost::variant,空指针或工具集中的等效项。