В чем разница между 2 объектами (указатели, c ++) - PullRequest
0 голосов
/ 03 апреля 2020

Мне интересно, в чем разница между этими двумя строками:

Cat* myCat = new Cat();    // 1
Cat yourCat = new Cat();   // 2

Спасибо за все ответы, но я должен добавить некоторые детали: я сталкиваюсь с обеими реализациями и не знаю Разница в использовании между ними. Когда использовать какую строку, каковы последствия выбора каждого?

Ответы [ 3 ]

1 голос
/ 03 апреля 2020

Разница между этими двумя объявлениями

Cat* myCat = new Cat();    // 1
Cat yourCat = new Cat();   // 2

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

В этом случае вам нужно будет «вручную» удалить указанный объект с помощью оператора delete.

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

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

Коротко говоря, в первом объявлении объявлен указатель на объект типа Cat. В то время как во втором объявлении объявлен объект типа Cat.

Вот демонстрационная программа

#include <iostream>

struct Cat
{
    Cat() : p( nullptr ) {}
    Cat( Cat *p ) : p( p == nullptr ? p : Cat( *p ) ) {}

    ~Cat() { delete p; }

    Cat *p;
};

int main()
{
    Cat* myCat = new Cat();    // 1
    Cat yourCat = new Cat();   // 2 

    delete myCat; 
}
0 голосов
/ 04 апреля 2020

Предполагая, что оператор приведения отсутствует (от Cat* до Cat) и конструктор по умолчанию используется по умолчанию (явно или неявно), мы можем сказать следующее

Cat yourCat = new Cat ();

Предыдущий строка недопустима, потому что new Cat возвращает адрес динамически размещенного объекта класса Cat, пока вы пытаетесь инициализировать объект cat yourCat, используя адрес.

Cat* myCat = new Cat;

Это правильный адрес. Инициализация указателя с использованием адреса, возвращенного новым.

Еще одна вещь,

Не используйте необработанный указатель, используйте умный

0 голосов
/ 03 апреля 2020
Cat* myCat = new Cat();    // 1

Это значение по умолчанию создает динамически распределенное Cat и помещает результирующий указатель на этот Cat в указатель, называемый myCat.


Cat yourCat = new Cat();   // 2

Это значение по умолчанию -строит динамически распределенное Cat, затем создает автоматически c -хранилище (или stati c -хранилище, если оно глобальное) Cat с именем yourCat из полученного указателя.

Является ли это допустимым, зависит от определения Cat.

Если у него есть конструктор, который принимает Cat*, то этот указатель передается в качестве аргумента конструктору, и мы не можем сказать из количество кода с учетом того, что он делает с этим указателем, или динамически выделенное значение Cat равно delete d или утечка.

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

Обратите внимание, что наличие такого конструктора было бы не-идиоматическим c и весьма необычным, поэтому у вашего класса , вероятно, такого нет.


Если конструктор по умолчанию для Cat удален, тогда n любая строка будет компилироваться!

...