Какие стандартные классы C++ не могут быть повторно реализованы в C++?

Начните присваивать его переменной, чтобы сохранить ссылку, то есть

var aForm = new form1("somename");

, затем назначить свойства

aForm.SomeProperty = SomeValue;
aForm.SomeSetting = SomeSettingValue;

Затем запустить его

application.run(aForm);
9
задан Eclipse 30 October 2008 в 13:59
поделиться

8 ответов

std::type_info простой класс, хотя заполнение его требует typeinfo: конструкция компилятора.

Аналогично, исключениями являются обычные объекты, но выдавание исключения требует волшебства компилятора (где исключения выделяются?).

Вопрос, мне, "как близко может мы добираться до std::initializer_lists без волшебства компилятора?"

Рассмотрение Википедии, std::initializer_list<typename T> может быть инициализирован чем-то, что много походит на литерал массивов. Давайте попытаемся дать наш std::initializer_list<typename T> конструктор преобразования, который берет массив (т.е. конструктор, который берет отдельный аргумент T[]):

namespace std {
     template<typename T> class initializer_list {
         T internal_array[];
         public:
         initializer_list(T other_array[]) : internal_array(other_array) { };

         // ... other methods needed to actually access internal_array
     }
}

Аналогично, класс, который использует a std::initializer_list делает так путем объявления конструктора, который берет сингл std::initializer_list аргумент - иначе конструктор преобразования:

struct my_class {
    ...
    my_class(std::initializer_list<int>) ...
}

Так строка:

 my_class m = {1, 2, 3};

Заставляет компилятор думать: "Я должен вызвать конструктора для my_class; my_class имеет конструктора, который берет a std::initializer_list<int>; Я имею int[] литерал; я могу преобразовать int[] к a std::initializer_list<int>; и я могу передать это my_class конструктор" (считанный в конец ответа прежде, чем сказать мне, что C++ не позволяет двум неявным пользовательским преобразованиям быть объединенными в цепочку).

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

int arry[] = {1, 2, 3};
my_class = arry;

Кроме того, я не потрудился смешивать с rvalue ссылками.

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

5
ответ дан 4 December 2019 в 14:32
поделиться

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

1
ответ дан 4 December 2019 в 14:32
поделиться

C++ позволяет компиляторам определять в других отношениях неопределенное поведение. Это позволяет реализовать Стандартную Библиотеку в нестандартном C++. Например, "onebyone" задается вопросом о atexit (). Устройства записи библиотеки могут принять вещи о компиляторе, который заставляет их непортативный C++ работать хорошо на их компилятор.

1
ответ дан 4 December 2019 в 14:32
поделиться

Единственный другой, о котором я мог думать, был type_info классом, возвращенным идентификатором типа. Насколько я могу сказать, VC ++ реализует это путем инстанцирования всех необходимых type_info классов статически во время компиляции и затем просто кастинга указателя во времени выполнения на основе значений в vtable. Это вещи, которые могли быть сделаны с помощью C код, но не приспосабливающим стандарту или портативным способом.

5
ответ дан 4 December 2019 в 14:32
поделиться

Что-либо, что "рычаги во время выполнения в" в определенных точках вероятны не быть реализуемыми как портативная библиотека на гипотетическом языке "C++, исключая ту вещь".

Так, например, я думаю, что atexit () в <cstdlib> не может быть реализован просто как библиотека, так как нет никакого другого пути в C++, чтобы гарантировать, что это называют в правильное время в последовательности завершения, которая является перед любым глобальным деструктором.

Конечно, Вы могли утверждать, что функции C "не рассчитывают" для этого вопроса. В этом случае станд.:: неожиданный может быть лучший пример, по точно той же причине. Если бы это не существовало, то не было бы никакого способа реализовать его, не переделывая код исключения, испускаемый компилятором.

[Редактирование: Я просто заметил, что корреспондент на самом деле спросил, какие классы не могут быть реализованы, не, какие части стандартной библиотеки не могут быть реализованы. Таким образом, на самом деле эти примеры строго не отвечают на вопрос.]

1
ответ дан 4 December 2019 в 14:32
поделиться

MSalter указывает на printf/cout/stdout в комментарии. Вы могли реализовать любой из них с точки зрения того из других (я думаю), но Вы не можете реализовать полный набор их вместе без вызовов ОС или волшебства компилятора, потому что:

  1. Это все способы получить доступ к потоку стандартного вывода процесса. Необходимо наполнить байты где-нибудь, и это является определенным для реализации в отсутствие этих вещей. Если я не забыл другой способ получить доступ к нему, но точка - Вы, не может реализовать стандартный вывод кроме через определенное для реализации "волшебство".

  2. У них есть "волшебное" поведение во времени выполнения, которое я думаю, не мог отлично подражаться чистой библиотекой. Например, Вы не могли только использовать статическую инициализацию для построения суда, потому что порядок статической инициализации между единицами компиляции не определяется, таким образом, не было бы никакой гарантии, что это будет существовать вовремя, чтобы использоваться другими статическими инициализаторами. stdout, возможно, легче, так как это - просто fd 1, таким образом, любой аппарат, поддерживающий его, может быть создан вызовами, это передается в то, когда они видят его.

1
ответ дан 4 December 2019 в 14:32
поделиться

Я думаю, что Вы довольно в безопасности в этом отношении. C++ главным образом служит толстым слоем абстракции вокруг C. Так как C++ является также надмножеством самого C, примитивы базового языка почти всегда реализуются без классов (в C-стиле). Другими словами, Вы не собираетесь находить много ситуаций как Java Object который является классом, которому трудно кодировали особое значение в компилятор.

0
ответ дан 4 December 2019 в 14:32
поделиться

Снова от C++ 0x, я думаю, что потоки не были бы реализуемы как портативная библиотека на гипотетическом языке "C++ 0x со всеми стандартными библиотеками кроме потоков".

[Редактирование: просто для уточнения, кажется, существует некоторое разногласие относительно того, что это означало бы "реализовывать потоки". Что я понимаю, что это для значения в контексте этого вопроса:

1) Реализуйте C++ 0x поточная обработка спецификации (независимо от того, что это оказывается). Отметьте C++ 0x, который является тем, о чем я и корреспондент оба говорим. Не любая другая спецификация поточной обработки, такая как POSIX.

2) без "волшебства компилятора". Это означает ничего не добавлять к компилятору, чтобы помочь Вашей реализации работать и не полагаться ни на какие нестандартные детали реализации (такие как конкретное расположение стека или средство переключения стеков или непортативных системных вызовов для установки синхронизированного прерывания) для создания библиотеки потока, которая работает только над конкретной реализацией C++. Другими словами: чистый, портативный C++. Можно использовать сигналы и setjmp/longjmp, так как они являются портативными, но мое впечатление, это недостаточно.

3) Примите C++ 0x компилятор, за исключением того, что он пропускает все части C++ 0x поточная обработка спецификации. Если все, что это пропускает, является некоторой структурой данных (который хранит значение выхода и синхронизацию, примитивную используемый соединением () или эквивалентный), но волшебство компилятора реализовать потоки присутствует, то, очевидно, что структура данных могла быть добавлена как сторонний портативный компонент. Но это - своего рода тусклый ответ, когда вопрос был, о котором C++ 0x стандартные классы библиотеки требуют волшебства компилятора поддерживать их. IMO.]

0
ответ дан 4 December 2019 в 14:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: