Несколько способов создать экземпляр класса в c++. В чем разница?
ifstream in1;
ifstream in2();
ifstream *in3 = new ifstream();
В чем разница? Между 2 и 3 еще понятно: один экземпляр хранится на куче, другой в стеке. А что с первым?
#include <iostream>
using namespace std;
class Class
{
public:
Class() {}
Class(int a) {}
};
int main()
{
Class a;
Class b(4);
Class c();
Class *d = new Class();
}
Как-то так выглядит аналогичный код на ассемблере. Компилировал с ключом -O0. Хочу заметить, что Class c(); игнорируется компилятором Такой вопрос: где хранится класс и указатель this в (1,2) и 4 случае?
Ответы (2 шт):
Между 1 и 3 еще понятно: один экземпляр хранится на куче. А второй это прототип функции. Объявление с круглыми скобками будет объявлением объекта лишь в том случаи, если в круглых скобках указаны аргументы конструктора. Объект можно создать также с помощью универсального инициализатора. Объявление
fstream in2{};(фигурные скобки) будет идентично fstream in2;
P.S. Что касается третьего объекта, то new ifstream() это конструкция New-expression, для которой круглые скобки хоть и лишние, но допустимые. Это создания объекта в куче, а не объявление...
Исправление ответа, спасибо за комментарий @ARHovsepyan.
Плохо посмотрел ассемблерный вывод прежде чем писать.
Во втором случае ты создаёшь не экземпляр объекта, а объявляешь функцию которая возвращает ifstream.
В то же время если передать аргументы то это уже будет вызов конструктора Например пример для std::vector
std::vector<int> arr(5, 10);
в результате arr=[10,10,10, 10, 10];
P.S.
Ещё немного вариантов создания экземпляров:
- например если использовать фигурные скобки будет вызван конструктор принимающий std::initializer_list:
std::vector<int> arr{5, 10}; // arr = [5,10]
- Так же возможен вариант с размещающим new
char data[sizeof(std::vector<int>)];
std::vector<int>* arr = new (data) std::vector<int>();
