Инициализация объекта с новым оператором и без него - программирование
Подтвердить что ты не робот

Инициализация объекта с новым оператором и без него

Если у меня есть класс Rectangle

class Rectangle{

private:
    double width;
    double height;


public:
void    Set(double w , double l){
    width   = w;
    height  = l;
}
};

и я уменьшаю объект такой:

Rectangle *Obj;

а затем попытайтесь инициализировать его свойства:

Obj->Set(3,5);

компилятор показывает во время выполнения: The variable 'Obj' is being used without being initialized.

Проблема может быть решена с помощью:

Rectangle *Obj=new Rectangle;

Я бы спросил о причине! И почему компилятор не обнаруживает ошибок во время компиляции?

4b9b3361

Ответ 1

Rectangle *Obj;

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

Решение использует либо new, как вы предполагали, или объявляет экземпляр Rectangle следующим образом:

Rectangle Obj;

который вызовет конструктор по умолчанию. Затем вы можете установить своих участников с помощью

Obj.Set(3, 5);

Ответ 2

и я уменьшаю объект такой:

Rectangle *Obj;

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

Ответ 3

Ммм немного путаницы:

компилятор показывает во время выполнения: переменная 'Obj' используется без инициализации

Это то, что вы бы назвали время компиляции. Просто выправьте жаргон.

Кроме того, самым простым способом было бы

Rectangle Obj;
Obj.Set(3,5);

что достаточно для большинства сценариев, кроме динамических распределений или полиморфных контейнеров:

std::vector<Shape*> v;
v.push_back(new Rectange());
v.back()->Set(3,5);

v.push_back(new Circle());
v.back()->Set(3,5);

//

Хотя при использовании new вы также должны помнить delete. Это может быть довольно кошмаром (в свете исключений тоже). Я предлагаю:

std::vector<std::shared_ptr<Shape*> > v;
v.push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);

v.push_back(std::make_shared<Circle>());
v.back()->Set(3,5);

Ответ 4

С Rectangle *Obj; вы объявляете указатель на Rectangle, но вы не сказали Obj, к которому Rectangle должен указывать. Вы можете установить или создать экземпляр Obj позже на существующий Rectangle или только если вам нужно.

С++ - это все, что дает вам точный контроль над вашей памятью и производительностью. На самом деле, почему он используется в некоторых встроенных средах! Автоматическое создание экземпляра Obj создает несколько "проблем"

  • Когда мы освободим Obj?
  • Кто освобождает Obj?
  • Как насчет влияния производительности создания Rectangle на кучу?
  • Это среда, в которой у нас достаточно ресурсов (памяти, процессора и т.д.), чтобы создать Rectangle, особенно если он большой.
  • Проводите ли вы адрес Obj где-нибудь, а затем создаете экземпляр его во время выполнения через какой-то сложный метод, который мы не можем проанализировать статически?

То, что вы делаете, не является синтаксической ошибкой, и это то, что компиляторы бросают ошибки при ошибках при компиляции. Анализатор (один встроен в профессионал Visual Studio 2010) может предупредить вас о том, что вы используете неинициализированную переменную, хотя это необязательно, и вам может потребоваться включить его.

Ответ 5

указатель без new объявляет что-то без памяти. SO u нужно использовать новый с указателем. Однако Прямоугольник прямоугольный; будет по умолчанию выделять память.

чтобы проверить это, сделать конструктор в классе Rectangle, например,

void Rectangle
{
  cout<<"Rectangle Constructor";
}

тогда в главном

Rectangle *rect; -->>O/P  -- "Nothing"
Rectangle rect2; -->>O/P  -- Rectangle Constructor
rect=new Rectangle; -->>O/P  -- Rectangle Constructor

Ответ 6

почему компилятор не показывает ошибки при компиляции времени?

Потому что он синтаксически правильный. Однако такие утверждения приведут к undefined поведению, интеллектуальные компиляторы всегда выдают предупреждение.

В g++ вы можете включить такое предупреждение о компиляторе в ошибки.

Ответ 7

Прямоугольник оператора *obj означает, что существует указатель, который будет указывать на переменную прямоугольника типа.

С помощью этого утверждения вы просто создаете указатель не экземпляр прямоугольника объекта для использования этого указателя вы должны сохранить адрес переменной типа прямоугольника в указателе

Два способа сделать это:

obj=new rectangle;  //variable is created in the stack storage

или

rectangle r;
obj =&r;     //variable is created in the heap storage