cpp-ru / ideas

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

Предварительное описание методов #548

Open osheter opened 1 year ago

osheter commented 1 year ago

Разрешить предварительное описание методов, не описывая весь класс. Использовать вместо pimpl.

// h-файл

class foo;
int foo::bar() const;

// cpp-файл

class foo
{ 
public:
  int bar() const { return 0; }
};
sergii-rybin-tfs commented 1 year ago

Использовать вместо pimpl.

И отказаться от возможности использовать конструкторы и деструкторы ?

osheter commented 1 year ago

Нет конечно. Экземпляр может быть создан функцией-фабрикой, возвращающей указатель. Это удобно например для тестов. Можно писать их имея только заголовок с набором методов и функцией-фабрикой. А реализацию будет писать совсем другой человек даже в другом DLL

вт, 21 февр. 2023 г. в 10:32, Sergii Rybin @.***>:

Использовать вместо pimpl.

И отказаться от возможности использовать конструкторы и деструкторы ?

— Reply to this email directly, view it on GitHub https://github.com/cpp-ru/ideas/issues/548#issuecomment-1438042198, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU3WCIGEMWX56JP54G2FDPTWYR4QBANCNFSM6AAAAAAVCTJX3E . You are receiving this because you authored the thread.Message ID: @.***>

sergii-rybin-tfs commented 1 year ago

Для Вашего класса компилятор, согласно стандарта, обязан сгенерировать деструктор, если оригинальный недоступен в области видимости(Что достаточно странно и абсурдно для многих, и приводит к частым ошибкам в программах в виде утечек ресурсов и дэдлоков и прочее). Подробности тут: #476. Конкретно для вашего случая pimpl будет утечка ресурсов. Если же деструктор будет видимым, то это уже совсем не Pimpl.

osheter commented 1 year ago

Видимо, я недостаточно ясно объяснил свою мысль. Моя идея не в том, чтобы кардинально менять стандарт языка. Экземпляр конечно создается и уничтожается там, где есть полное описание класса. Это его реализация. Тем не менее существуют ситуации, когда внутреннее устройство класса, его поля и т.п. не требуется для его использования. В таких случаях для пользователя достаточно видеть только указатель/ссылку и публичные методы. Конечно, создание и уничтожение происходит там, где класс полностью описан, но например тест может получать ссылку и выполнять тестирование, "зная" только сигнатуры публичных методов. Приведу пример.

//-------------- main cpp-file -------------- struct foo; void foo_test_implementation(foo&);

struct foo { void set(int y) { x = y; } int get() const { return x; } static void test() { foo f; foo_test_implementation(f); } private: int x; }

//---------------- test cpp-file ------------ class foo; static void foo::test(); int foo::set(int); int foo::get() const;

void foo_test_implementation(foo& f) { f.set(123); assert(f.get()==123); }

void main() { foo::test(); }

Здесь реализация теста получает ссылку на экземпляр и вызывает его публичные методы по описаниям сигнатур. Как именно устроен класс, ни для пользователя ни для компилятора не важно.

On Tue, Feb 21, 2023, 13:11 Sergii Rybin @.***> wrote:

Для Вашего класса компилятор, согласно стандарта, обязан сгенерировать деструктор, если оригинальный недоступен в области видимости(Что достаточно странно и абсурдно для многих, и приводит к частым ошибкам в программах в виде утечек ресурсов и дэдлоков и прочее). Подробности тут: #476 https://github.com/cpp-ru/ideas/issues/476. Конкретно для вашего случая pimpl будет утечка ресурсов. Если же деструктор будет видимым, то это уже совсем не Pimpl.

— Reply to this email directly, view it on GitHub https://github.com/cpp-ru/ideas/issues/548#issuecomment-1438295552, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU3WCIDSAKBBPMH6RJOLQIDWYSPE3ANCNFSM6AAAAAAVCTJX3E . You are receiving this because you authored the thread.Message ID: @.***>

sergii-rybin-tfs commented 1 year ago

Тем не менее существуют ситуации, когда внутреннее устройство класса, его поля и т.п. не требуется для его использования. В таких случаях для пользователя достаточно видеть только указатель/ссылку и публичные методы.

У линкера ( в сигнатуре метода ) нет информации о том публичный метод или не публичный. Также поломается несколько других функций языка с++.

tea commented 1 year ago

Возникает проблема с overloads. Например, есть внешнее определение void foo::bar(int), а в классе есть void bar(long). Вызываем m_foo->bar(1L), и выбор конкретного метода оказывается зависимым от того, видим мы класс или нет. Кроме того, сама эта проблема (отвязывание использования класса от его деталей реализации), если я правильно понимаю, может/должна решаться сама собой при использовании модулей.

osheter commented 1 year ago

Если в классе нет описанного метода, то программа не соберется.

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

On Mon, May 29, 2023, 16:20 Andrey Turkin @.***> wrote:

Возникает проблема с overloads. Например, есть внешнее определение void foo::bar(int), а в классе есть void bar(long). Вызываем m_foo->bar(1L), и выбор конкретного метода оказывается зависимым от того, видим мы класс или нет. Кроме того, сама эта проблема (отвязывание использования класса от его деталей реализации), если я правильно понимаю, может/должна решаться сама собой при использовании модулей.

— Reply to this email directly, view it on GitHub https://github.com/cpp-ru/ideas/issues/548#issuecomment-1567134347, or unsubscribe https://github.com/notifications/unsubscribe-auth/AU3WCIE352SPSMEP6M5DJTDXISPDPANCNFSM6AAAAAAVCTJX3E . You are receiving this because you authored the thread.Message ID: @.***>