cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
88 stars 0 forks source link

Частичное описание структуры/класса (только методы, не обязательно все) #465

Open osheter opened 3 years ago

osheter commented 3 years ago

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

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

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

Конкретный синтаксис данной идеи может быть реализован с помощью extern или введением нового зарезервированного слова partial или forward (partial class, like in C#) или с помощью атрибута [[partial]] перед class/struct.

Пример использования:

// .h file 
extern struct worker
{
  void work();
};

inline void do_work(worker& w)
{
  w.work();
}
// .cpp file
struct worker
{
  void work(); // optional declaration
private:
  int x=0;
};

void worker::work() 
{
  x++;
}

Другой способ (менее удобный на мой взгляд) это разрешить объявлять только заголовок метода:

class foo;
void foo::bar() const; // is it automatically public?
static foo::bar2();

Должно ли частичное описание класса затем повторяться в полном описании? Скорее всего не обязательно, хотя дублирование описаний не запрещено. Возможно ли существование класса на основании только частичных описаний? Наверное нет, потому что, если частичного описания достаточно, то зачем объявлять его частичным?