Создание объекта класса в С++

Сначала я из JAVA.

В java мы создаем объект класса таким образом.

Example example=new Example();

Класс Example может иметь конструктор или не может иметь конструктор.

Я могу использовать то же самое в С++, как это

Example* example=new Example();

Если конструктор является обязательным.

Из этого учебника http://www.cplusplus.com/doc/tutorial/classes/

Я понял, что мы можем создать такой объект.

Example example;

Для этого не требуется конструктор.

У меня есть два вопроса.

1) В чем разница между способом создания объектов класса.

2) Если я создаю такой объект, как Example example;, как использовать его в одноэлементном классе.

как обычно, мне нравится.

Sample* Singleton::get_sample() {
    if (sample == NULL) {
        sample = new Sample();
    }
    return sample;
}

Прошу вас, если я ошибаюсь.

Ответ 1

Я могу использовать то же самое в С++, как это [...] Где конструктор является обязательным. Из этот учебник Я понял, что мы можем создать такой объект [...], который не требует конструктора.

Это неправильно. Конструктор должен существовать для создания объекта. Конструктор может быть определен неявно компилятором при некоторых условиях, если вы его не предоставите, но в конечном итоге конструктор должен быть там, если вы хотите, чтобы объект был создан. Фактически, время жизни объекта определяется для начала, когда возвращается процедура конструктора.

Из пункта 3.8/1 стандарта С++ 11:

[...] Время жизни объекта типа T начинается, когда:

- получено хранилище с надлежащим выравниванием и размером для типа T, а

- если объект имеет нетривиальную инициализацию, его инициализация завершена.

Следовательно, должен присутствовать конструктор.

1) В чем разница между способом создания объектов класса.

Когда вы создаете экземпляр объекта с автоматическим временем хранения, как это (где X - некоторый класс):

X x;

Вы создаете объект, который будет автоматически уничтожен, когда он выходит за рамки. С другой стороны, когда вы делаете:

X* x = new X();

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

В Modern С++ это считается сомнительной практикой программирования: хотя указатели важны, потому что они позволяют реализовать ссылочную семантику, необработанные указатели являются плохими, потому что они могут привести к утечкам памяти (объекты, переживающие все их указатели и никогда не уничтожаемые) или в оборванных указателях (указатели ожидают объект, на который они указывают, потенциально вызывая поведение Undefined при разыменовании).

Фактически, при создании объекта с new вам всегда нужно помнить об уничтожении его с помощью delete:

delete x;

Если вам нужна эталонная семантика и вынуждены использовать указатели, в С++ 11 вместо этого следует использовать умные указатели:

std::shared_ptr<X> x = std::make_shared<X>();

Умные указатели заботятся о проблемах с управлением памятью, что дает вам головную боль с необработанными указателями. Умные указатели на самом деле почти такие же, как ссылки на объекты Java или С#. "Почти" необходимо, потому что программист должен заботиться о том, чтобы не вводить циклические зависимости посредством владения интеллектуальными указателями.

2) Если я создаю объект, например, пример; как использовать это в одноэлементном классе.

Вы можете сделать что-то вроде этого (упрощенный код):

struct Example
{
    static Example& instance()
    {
        static Example example;
        return example;
    }

 private:

    Example() { }
    Example(Example const&) = delete;
    Example(Example&&) = delete;
    Example& operator = (Example const&) = delete;
    Example& operator = (Example&&) = delete;

};

Ответ 2

Example example;

Это объявление переменной с именем example типа example. Это будет по умолчанию инициализировать объект, который включает вызов его конструктора по умолчанию. Объект будет иметь автоматическую продолжительность хранения, что означает, что он будет уничтожен, когда он выходит за рамки.

Example* example;

Это объявление переменной с именем example, которая является указателем на example. В этом случае инициализация по умолчанию оставляет его неинициализированным - указатель указывает нигде в частности. Здесь нет объекта example. У объекта указателя есть время автоматического хранения.

Example* example = new Example();

Это объявление переменной с именем example, которая является указателем на example. Этот объект указателя, как указано выше, имеет время автоматического хранения. Затем он инициализируется результатом new Example();. Это выражение new создает объект example с динамической продолжительностью хранения, а затем возвращает указатель на него. Таким образом, указатель example теперь указывает на этот динамически выделенный объект. Объект example инициализируется значением, который вызывается конструктором, предоставленным пользователем, если он есть или иным образом инициализирует все члены в 0.

Example* example = new Example;

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

Динамически выделенный объект должен быть delete d (возможно, с delete example;).

Ответ 3

1) В чем разница между способом создания класса объекты.

Первый - это указатель на построенный объект в куче (через new). Второй - это объект, который неявно построен. (Конструктор по умолчанию)

2) Если я создаю объект, например, пример; как использовать это в singleton class.

Это зависит от ваших целей, проще всего поставить его как участника в классе просто.

Образец одноэлементного класса, который имеет объект из класса Example:

class Sample
{

    Example example;

public:

    static inline Sample *getInstance()
    {
        if (!uniqeInstance)
        {
            uniqeInstance = new Sample;
        }
        return uniqeInstance;
    }
private:
    Sample();
    virtual ~Sample();
    Sample(const Sample&);
    Sample &operator=(const Sample &);
    static Sample *uniqeInstance;
};

Ответ 4

Прежде всего, оба случая называет конструктор. Если вы пишете

Example *example = new Example();

тогда вы создаете объект, вызываете конструктор и извлекаете указатель на него.

Если вы пишете

Example example;

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

Что касается вопроса singleton, вы должны просто вызвать свой статический метод, написав:

Example *e = Singleton::getExample();

Ответ 5

Example example;

Здесь пример - объект в стеке.

Example* example=new Example();

Это можно разбить на:

Example* example;
....
example=new Example();

Здесь первый оператор создает пример переменной, который является "указателем на пример". Когда вызывается конструктор, память выделяется для него в куче (динамическое распределение). Ответственность программиста заключается в освобождении этой памяти, когда она больше не нужна. (С++ не содержит сборку мусора, например java).

Ответ 6

В первом случае вы создаете объект на heap с помощью new. Во втором случае вы создаете объект на stack, поэтому он будет удаляться при выходе из области видимости. В C++ вам нужно будет удалить объекты в heap, явно используя delete, когда они вам больше не нужны.

Чтобы вызвать статический метод из класса, do

Singleton* singleton = Singleton::get_sample();

в вашей основной функции или где угодно.

Ответ 7

1) В чем разница между способом создания объектов класса.

a) указатель

Example* example=new Example();
// you get a pointer, and when you finish it use, you have to delete it:

delete example;

b) Простая декларация

Example example;

вы получаете переменную, а не указатель, и она будет уничтожена из объявленной области видимости.

2) Синглтон С++

Этот вопрос SO может помочь вам

Ответ 8

Существует два способа создания/создания объекта в С++.

Первый:

MyClass myclass; // if you don;t need to call rather than default constructor    
MyClass myclass(12); // if you need to call constructor with parameters

Второй:

MyClass *myclass = new MyClass();// if you don;t need to call rather than default constructor
MyClass *myclass = new MyClass(12);// if you need to call constructor with parameters

В С++, если вы используете новое ключевое слово, объект будет храниться в куче. это очень полезно, если вы используете этот объект долгое время периода, и если вы используете первый метод, он будет храниться в стеке. он может использоваться только короткий период времени. Обратите внимание: если вы используете новое ключевое слово, помните, что оно вернет значение указателя. вы должны объявить имя с *. Если вы используете второй метод, он не удаляет объект в куче. вы должны удалить самостоятельно, используя ключевое слово delete;

delete myclass;