c ++ "интерфейс" -подобные классы, похожие на Java? - PullRequest
2 голосов
/ 20 ноября 2011

В Java вы можете определить интерфейс как класс без фактической реализации кода, а только для определения методов, которые класс должен реализовать.Эти типы могут быть переданы в качестве параметров для методов и возвращены из методов.В C ++ чистый виртуальный класс не может использоваться в качестве параметра или возвращаемого типа, насколько я могу судить.Есть ли способ имитировать классы интерфейса Java?

У меня есть строковый класс в C ++ и несколько подклассов для разных кодировок (таких как UTFxxx, ISOxxx и т. Д.), Которые происходят от базового строкового класса.Однако, поскольку существует так много разных кодировок, базовый класс не имеет осмысленной реализации.Но он хорошо послужил бы интерфейсом, если бы я мог обрабатывать его как свой собственный объект, а вызовы этого объекта вызывали бы правильный подкласс, которому он был унаследован.

Ответы [ 4 ]

3 голосов
/ 20 ноября 2011

Чисто-виртуальный класс может использоваться как тип возвращаемого значения, если вы используете только ссылку или указатель.

Фактически, в Java Interface foo = Implementer(); эквивалентно Interface* foo = Implementer();, а implements Foo равно public virtual Foo.

Вот пример Java:

interface Foo {
    public void doFoo();
}
class Bar implements Foo {
    public void doFoo() { }
}

Его аналог C ++:

struct Foo {
    virtual void doFoo() = 0;
    virtual ~Foo() { }
};
class Bar : public virtual Foo {
public:
    virtual void doFoo() { }
    virtual ~Bar() { }    
};

Правильно, C ++ будет жаловаться на неполный тип, если вы используете Foo foo;. Использование Foo& foo, Foo* foo или smart_pointer<Foo> foo - это то, что требуется.

В этом примере smart_pointer может быть scoped_ptr, unique_ptr или shared_ptr, в зависимости от того, хотите ли вы

  • просто умный указатель, который delete()s на уничтожение
  • умный указатель с семантикой перемещения
  • умный указатель, который делает подсчет ссылок

Обратите внимание, что для повышения интеллектуальных указателей, если вы их используете, используйте семантику get() / reset() для получения и установки значения указателя.

2 голосов
/ 20 ноября 2011

Вы не можете использовать чистый виртуальный класс по значению, но вы можете передать его по указателю или по ссылке.Это включает в себя возможность передавать его в виде интеллектуального указателя, такого как unique_ptr или shared_ptr.

. Также следует убедиться, что вы пометили деструктор в интерфейсе ключевым словом virtual, чтобыпредотвратить возможные утечки памяти.

1 голос
/ 20 ноября 2011

Вот определение интерфейса в Google C ++ Style:

Класс - это чистый интерфейс, если он удовлетворяет следующим требованиям:

  • Он имеет только открытые чисто виртуальные ("= 0") и статические методы (но деструктор см. Ниже).
  • Возможно, в нем нет нестатических элементов данных.
  • Нет необходимости определять конструкторы. Если предоставляется конструктор, он не должен принимать аргументов и должен быть защищен.
  • Если это подкласс, он может быть получен только из классов, которые удовлетворяют этим условиям и помечены суффиксом интерфейса.

Класс интерфейса никогда не может быть напрямую создан из-за чисто виртуальных методов, которые он объявляет. Чтобы убедиться, что все реализации интерфейса могут быть уничтожены правильно, интерфейс должен также объявить виртуальный деструктор (в исключении из первого правила это не должно быть чисто). Подробнее см. Страуструп, Язык программирования C ++, 3-е издание, раздел 12.4.

Ознакомьтесь с Руководством по стилю Google C ++, разделами «Множественное наследование» и «Интерфейс». http://google -styleguide.googlecode.com / SVN / багажник / cppguide.xml

1 голос
/ 20 ноября 2011

Конечно, вы можете использовать класс, такой как интерфейс, но это не конструкция языка, это просто класс только с чисто виртуальными методами.Помните, что интерфейсы были просто способом, которым Java делала множественное наследование без всех хитрых проблем (две копии класса прародителя, несколько переменных с одним именем и т. Д.)

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