Автоматизировать развертывание классов C ++ & # 8212; Есть ли простой способ?

StackOverflow https://stackoverflow.com/questions/1621446

Вопрос

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

Я представляю себе инструмент, используемый как часть процесса создания. Вы хотите, чтобы ваши публичные заголовки были классами pimpl'd, поэтому вы предоставляете некоторый входной файл, скажем pimpl.in, в котором перечислены классы (реализованные un-pimpl'd), которые вы хотите обернуть, затем этот файл проверяется, классы pimpl генерируются, и только их заголовки (не заголовки исходного класса) устанавливаются во время 'make install'. Проблема в том, что я не вижу способа сделать это без полноценного синтаксического анализатора C ++, что даже поставщики компиляторов не могут сделать правильно. Может быть, классы могли бы быть написаны так, чтобы упростить работу внешнего инструмента, но я уверен, что в конечном итоге я пропущу все виды угловых случаев (например, шаблонные классы и / или шаблонные функции-члены).

Есть идеи? Кто-нибудь еще пришел с решением этой проблемы?

Это было полезно?

Решение

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

Другие советы

Я не говорю, что это хорошо (просто то, что пришло в голову).
Но вы можете поэкспериментировать с перегрузкой оператора - >

#include <memory>
#include <iostream>

class X
{
    public:
    void plop()
    {
        std::cout << "Plop\n";
    }
};

class PimplX
{
    public:
        PimplX()
        {
            pimpl.reset(new X);
        }
        X* operator->()
        {
            return pimpl.get();
        }
    private:
        PimplX(PimplX const&);
        PimplX& operator=(PimplX const&);
        std::auto_ptr<X>    pimpl;
};   


int main()
{    
    PimplX      x;

    x->plop();
}

Один из вариантов - использовать интерфейсный класс:

class ClassA {
  virtual void foo() = 0;
  static ClassA *create();
};

// in ClassA.cpp

class ImplA : public ClassA {
/* ... */
};
ClassA *ClassA::create() {
  return new ImplA();
}

Это, однако, увеличивает издержки при получении указателей на функции vtable.

Кроме этого, я не могу думать ни о каком таком инструменте. Как вы сказали, синтаксический анализ C ++ является нетривиальным, и есть другие языки, в которых это не представляет особой проблемы (например, C # или Java с поздним связыванием всего, так что вы можете изменить их расположение в памяти позже без проблем).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top