SWIG: частные определения типов, используемые в публичных функциях - PullRequest
1 голос
/ 08 февраля 2011

Я часто даю своим классам закрытую typedef для ссылки на себя следующим образом:

class MyClass {
  private:
    typedef MyClass Self;
  public:
    void DeepCopyFrom(const Self& other);
    ...
};

Я сейчас оборачиваю свой код C ++ с помощью SWIG, который жалуется на такие typedefs:

error: ‘typedef class MyClass MyClass::Self’ is private

Код оболочки, который вызывает эту ошибку, выглядит следующим образом:

SWIGINTERN PyObject *_wrap_MyClass_DeepCopyFrom(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  MyClass *arg1 = (MyClass *) 0 ;
  MyClass::Self *arg2 = 0 ;
  (...)

Ошибка компилятора возникает в последней строке над многоточием.

Есть ли способ сообщить SWIGне использовать приватные определения типов, а вместо этого просто использовать полное имя типа?

Ответы [ 4 ]

2 голосов
/ 08 февраля 2011

Я предлагаю сделать это простым (r): просто удалите typedefs и напишите вместо этого имя класса.

Если вы действительно ненавидите это, вы можете сказать SWIG %ignore "неработающие" методы, а затем%extend классы с методами-обертками, вызывающими реальные.Если количество классов и методов, которые вы связываете, не является небольшим по сравнению с общей базой кода, это лекарство, вероятно, хуже, чем болезнь.

1 голос
/ 08 февраля 2011

SWIG по умолчанию не будет обрабатывать какие-либо определения типа или объявления или что-либо в разделе private. Следовательно, он предполагает (когда видит const Self&), что Self - это какой-то неизвестный тип из заголовка или чего-то еще, он оставляет его как таковой и генерирует код-обертку с оставленным там Self. Проблема в том, что этот код-обертка является функцией, внешней по отношению к классу, и, поскольку MyClass::Self является закрытой, ваш компилятор генерирует ошибку. С моим кодом произошло то же самое: мне нужно было либо объявить typedef в секции public, либо переписать Self как MyClass. Изменение typedef на public имеет для меня наибольшее значение.

0 голосов
/ 08 февраля 2011

Когда вам нужен непрозрачный тип, используйте вместо него неполный класс (и заполните его в файле реализации, а не в заголовочном файле).

Но в вашем конкретном примере он не выглядит для меня какнепрозрачный тип должен быть использован.

0 голосов
/ 08 февраля 2011

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

Я полагаю, что вы могли бы использовать закрытый typedef внутри некоторых функций-членов или интерфейсов закрытых функций-членов. Но если вы хотите использовать его в публичном методе, имеет смысл только, чтобы typedef был публичным.

Я не знаю, что стандарт говорит об этом предмете, но я думаю, это одна из немногих серых областей. Я бы предположил, что это зависит от реализации компилятора от того, как обрабатывать определения типов в классе, который вы определяете, допустимо ли использование закрытого определения типов в публичном методе (или вообще вообще приемлемо). Чтобы быть в безопасности, я бы просто сделал это публичным.

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

Я думаю, вы просто слишком далеко зашли в идею инкапсуляции.

...