Lua и поддельные Typecast - PullRequest
       1

Lua и поддельные Typecast

0 голосов
/ 13 сентября 2011

Я работаю с 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{...}

У меня есть доступ к Foo и Foo::getBar() от Lua, дело в том, что тип возвращаемого объекта - Bar, а у меня нетдоступ к его BarDerivedX методам.

Насколько я понимаю, объекты / классы в Lua - это просто метатаблицы с функциями, назначенными клавишам, поэтому мне было интересно, есть ли способ скопировать эти дополнительные функции из BarDerivedX класс к Bar объекту (и будет ли это вообще работать?), также, это лучший способ сделать это или я должен привести его в C ++, прежде чем Lua получит к нему доступ?

Ответы [ 2 ]

5 голосов
/ 13 сентября 2011

Цель полиморфизма на любом языке - не заботиться о том, что это за тип. Если вы даете кому-либо, будь то Lua или C ++, объект Bar, тогда Bar должен иметь интерфейсы, необходимые людям для выполнения всего, что им нужно.

Это цель виртуальных функций. Виртуальная функция, определенная в Bar, может быть переопределена другим поведением в BarDerived1. Другой код не должен знать, что им передается производный класс; они могут просто взять Bar, как всегда.

Как правило, существует только две причины сделать класс производным от другого. Первый - полиморфизм: вы хотите специализировать класс, изменяя поведение определенных функций.

Другая причина - получить доступ к его реализации. Например, если вы создаете строку Unicode, вы можете использовать std :: basic_string для хранения закодированных данных. Затем вы можете в частном порядке получить из std :: basic_string, что позволит вам получить оптимизацию хранилища, которую имеет std :: basic_string, но вы предоставите другой интерфейс (поскольку частное наследование не позволяет внешнему миру знаю, что вы получили от него).

Если вы хотите, чтобы все использовали Bar объекты, которые могут иметь различное поведение в зависимости от производных классов, то вам следует использовать виртуальные функции и полиморфизм. Однако, если вы меняете интерфейс в производных классах, то это, вероятно, признак проблемы проектирования. Возможно, эти производные классы вообще не должны быть производными. Возможно, они должны быть полностью отдельными классами, которые может иметь или не иметь экземпляр Bar, основываясь на некоторых параметрах инициализации.

Трудно сказать больше без подробностей о том, что вы на самом деле делаете. Но в целом, если вы правильно используете полиморфизм на основе наследования, вам не нужно приводить от Bar к более производным версиям. Просто используйте интерфейс Bar.

2 голосов
/ 13 сентября 2011

Существует базовый принцип наследования классов:

Должна быть возможность взаимозаменять экземпляр суперкласса на экземпляр любого из его подклассов.

Если B является подклассом A, то во всех местах, где вы используете экземпляр A, вы должны иметь возможность использовать экземпляр B.

Если ваш код этого не делает - просто вы неправильно используете наследование. Определенно, вы не используете его правильно, если единственная причина, по которой вам нужен подкласс, состоит в том, чтобы создать коллекцию проще.

Как говорят другие, правильное решение - использовать «универсальный тип» в объявлении коллекции; Удалите Bar полностью, и в объявлении коллекции используйте boost::variant, нулевые указатели или эквивалент в вашем наборе инструментов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...