Явное создание экземпляра
Явное создание экземпляров можно использовать для создания шаблонного класса или функции, чтобы обойтись без их использования в коде. Так как при создании библиотеки ( .lib ) файлов, использующих шаблоны для распространения, определения шаблонов не помещаются в файлы объектов ( .obj ).
Примеры
Этот код явно создает экземпляры MyStack для int переменных и шести элементов:
template class MyStack;
Этот оператор создает экземпляр класса MyStack , но не резервирует пространство в памяти для полученного объекта. Код создается для всех членов.
В следующей строке явное создание экземпляра выполняется только для функции-члена конструктора.
template MyStack::MyStack( void );
Вы можете явно создавать экземпляры шаблонов функций с помощью определенного аргумента типа для их повторного объявления, как показано в примере в создании экземпляра шаблона функции.
Вы можете использовать extern ключевое слово, чтобы предотвратить автоматическое создание экземпляров элементов. Например:
extern template class MyStack;
Аналогично, определенные элементы можно пометить как внешние, для которых не был создан экземпляр.
extern template MyStack::MyStack( void );
Вы можете использовать extern ключевое слово для сохранения компилятора от создания одного кода экземпляра в нескольких модулях объектов. При вызове функции необходимо создать экземпляр шаблона функции с помощью указанных явных параметров шаблона по крайней мере в одном связанном модуле. В противном случае при создании программы вы получите ошибку компоновщика.
extern Ключевое слово в специализации применяется только к функциям-членам, определенным вне тела класса. Функции, определенные внутри объявления класса, рассматриваются как встраиваемые; для них всегда создаются экземпляры.
Несколько способов создать экземпляр класса в c++. В чем разница?
В чем разница? Между 2 и 3 еще понятно: один экземпляр хранится на куче, другой в стеке. А что с первым?
#include using namespace std; class Class < public: Class() <>Class(int a) <> >; int main()

Как-то так выглядит аналогичный код на ассемблере. Компилировал с ключом -O0. Хочу заметить, что Class c(); игнорируется компилятором Такой вопрос: где хранится класс и указатель this в (1,2) и 4 случае?
Отслеживать
32.2k 15 15 золотых знаков 61 61 серебряный знак 93 93 бронзовых знака
задан 16 мар 2020 в 17:20
89 1 1 серебряный знак 11 11 бронзовых знаков
скорее нужно спрашивать что со вторым
16 мар 2020 в 17:33
можете пояснить?
16 мар 2020 в 17:36
Что-то мне кажется, что одно из них не совсем правильное
16 мар 2020 в 17:37
дело в том, что все это компилируется
16 мар 2020 в 17:42
@suvitruf-says-reinstate-monica, чё за угар? есть вопрос, есть ответ и тут задним числом приезжает доп вопрос
19 мар 2020 в 8:39
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Между 1 и 3 еще понятно: один экземпляр хранится на куче. А второй это прототип функции. Объявление с круглыми скобками будет объявлением объекта лишь в том случаи, если в круглых скобках указаны аргументы конструктора. Объект можно создать также с помощью универсального инициализатора. Объявление fstream in2<> ;(фигурные скобки) будет идентично fstream in2 ;
P.S. Что касается третьего объекта, то new ifstream() это конструкция New-expression , для которой круглые скобки хоть и лишние, но допустимые. Это создания объекта в куче, а не объявление.
Отслеживать
ответ дан 16 мар 2020 в 17:47
AR Hovsepyan AR Hovsepyan
15.9k 3 3 золотых знака 14 14 серебряных знаков 30 30 бронзовых знаков
@Alex, согласен, стоит знать международные термины.
16 мар 2020 в 17:54
@AlexF, только, скорее не компилятор, а программист -)
16 мар 2020 в 19:39
Исправление ответа, спасибо за комментарий @ARHovsepyan.
Плохо посмотрел ассемблерный вывод прежде чем писать.
Во втором случае ты создаёшь не экземпляр объекта, а объявляешь функцию которая возвращает ifstream.
В то же время если передать аргументы то это уже будет вызов конструктора Например пример для std::vector
std::vector arr(5, 10);
в результате arr=[10,10,10, 10, 10];
Ещё немного вариантов создания экземпляров:
- например если использовать фигурные скобки будет вызван конструктор принимающий std::initializer_list:
std::vector arr; // arr = [5,10]
- Так же возможен вариант с размещающим new
char data[sizeof(std::vector)]; std::vector* arr = new (data) std::vector();
#19 – Создание классов и объектов

За урок вы на практике изучите использование классов и объектов. Вы познакомитесь с C++ ООП, научитесь строить классы и объекты на их основе.
Видеоурок
Создание классов
Для создания класса необходимо прописать ключевое слово class и далее название для класса. Общепринято начинать названия классов с буквы в верхнем регистре, но если этого не сделать, то ошибки не будет.
В любом классе можно создавать поля (переменные), методы (функции), а также конструкторы.
Создав новый класс и поместив туда какую-либо информацию мы можем создавать на основе него новые объекты. Объекты будут иметь доступ ко всем характеристикам класса, которые отмечены модификатором public .
Существует три модификатора доступа:
- public — данные будут видны повсюду, как в классе, так и вне его;
- protected — данные будут видны только в классе, где они были созданы, а также в классах наследниках;
- private — данные будут видны только в классе, где они были созданы.
Пример простого класса приведен ниже:
class Book < public: int pages; char name; float weight; void getInfoBook () < cout >;
На основе такого класса мы можем создать множество объектов. Каждый объект в данном случае будет представлять из себя конкретную книжку. Для каждого объекта мы можем указать уникальные данные: количество страниц, название книги и её вес.
Чтобы создать объект нам потребуется следующий код:
Book sherlock_holms; // Создание объекта sherlock_holms.getInfoBook(); // Вызов метода класса
Такой код можно прописать и в одной строке кода. Мы для наглядности разбили код в две строки.
Чтобы брать данные из класса через объект необходимо ставить точку и указывать имя переменной или функции, которую мы хотим взять.
Создание классов
#include #include using namespace std; class Building < private: int year; string type; public: void set_data(int y, string t) < year = y; type = t; >void get_info() < cout >; int main() < setlocale(LC_ALL, "RU"); Building school; //school.type = "Школа"; //school.year = 2000; school.set_data(2000, "Школа"); school.get_info(); Building house; //house.type = "Дом"; //house.year = 2010; house.set_data(2010, "Дом"); house.get_info(); return 0; >
Задание к уроку
Необходимо оформить подписку на проект, чтобы получить доступ ко всем домашним заданиям
Большое задание по курсу
Вам необходимо оформить подписку на сайте, чтобы иметь доступ ко всем большим заданиям. В задание входит методика решения, а также готовый проект с ответом к заданию.
PS: подобные задания доступны при подписке от 1 месяца
Как средствами C++ создать экземпляр класса, видимого из методов другого класса?
Но в других файлах CGameHudInstance уже не виден.
- Вопрос задан более трёх лет назад
- 8486 просмотров
Комментировать
Решения вопроса 2
full stack python back-end developer
Строго говоря, использование глобальных переменных в С++ встречается редко. Это допустимо, но по большей мере для обеспечения совместимости с С. В С++ для передачи контекста используют другие приемы, например «передачу по указателю» (ниже). Стоит также сказать, что глобальные переменные сопряжены с кое-какими нюансами, например, могут возникнуть проблемы с последовательностью инициализации.
Но, судя по Вашему вопросу, Вам не нужны глобальные переменные. Достаточно будет кода на подобие этого:
/* * gameinstancehandler.h */ class GameInstanceHandler < public: GameInstanceHandler(CGameHud *instance): mInstance(instance)<>private: CGameHud *mInstance; // something other here >
#inlucde int main(int argc, char **args)
Здесь контекст передается по указателю. Объекты, поведение которых зависит от других, уже созданных объектов, просто получают указатели на них в конструкторе, сохраняют его «у себя» и взаимодействуют с ними через сохраненную копию указателя.
P.S. Поскольку вопрос новичковый, позволю себе дать еще один совет: во время объявления указателя пишите звездочку перед идентификатором, а не после типа.
int *a; // хорошо, a — это указатель. int* b; // плохо, но допустимо. int* c, d; // совсем плохо, c — указатель на int, d — просто переменная типа int. int *e, *f; // при такой же записи все понятно сразу.