Можно ли объявить объект одного класса в конструкторе другого класса в C ++? - PullRequest
2 голосов
/ 01 августа 2011

Можно ли инициализировать объекты одного класса в конструкторе другого класса в c ++?Обычно я объявляю объекты только в main (), однако мне любопытно узнать, возможно ли это, и это хорошая практика.Каковы последствия с «новым» и делом без «нового» оператора.Где это разрушается?

например Предполагается одно пространство имен и пример с оператором "new"

class A{
private:
protected:
int *w, int *h;
public:
A(){
 w = new int;
 h = new int;
 };
virtual int area (return ((*w)*(*h)) ;)
virtual ~A()
 {
  delete w;
  delete h;
 }
}

class B{
public:
B()
{
 A a1; // This is usually in the main();
 // Is this good practice
 //Where will the object be destroyed
}
virtual ~B();
}

Ответы [ 3 ]

2 голосов
/ 01 августа 2011

По поводу вашего фактического вопроса, да, это очень хорошая практика (если говорить об объявлении A внутри конструктора B). Это сработает и правильно вызовет деструктор А.

Однако: В размещенном вами фрагменте кода выделение двух объектов в конструкторе A - это , а не . Если operator new для h не пройден, то w будет пропущен. Деструктор A не будет вызван, если исключение выдается внутри его конструктора. Таким образом, w не будет удален, если new int сгенерирует h.

2 голосов
/ 01 августа 2011

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

Также обратите внимание, что «Каковы последствия с« новым »и делом без« нового »оператора».не проблемаЕсли бы они не были указателями (h & w), они были бы созданы по умолчанию при создании класса.Вы можете инициализировать объекты без указателя, хотя, если вы хотите, с помощью списка инициализатора, подобного следующему:

private: 
    int w;
    int h;

public:
    A() : w(0), h(0){ /* already done. */ };

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

-w00te

2 голосов
/ 01 августа 2011

В чем проблема? Конструктор - это просто обычная функция для ваших целей, поэтому все, что вы делаете, это объявляете локальный объект a1 типа A, который удаляется в конце области действия функции.

Обратите внимание, что ваш класс A, вероятно, очень опасно разработан (подумайте о копировании, назначении и исключениях), и, вероятно, совершенно нет необходимости выделять динамическое хранилище для A членов.


Обновление: Вот пример того, что вы могли иметь в виду:

class Rectangle
{
  unsigned int h, w;
public:
  Rectangle() : h(0), w(0) { }
  Rectangle(unsigned int height, width) : h(height), w(width) { }
  virtual ~Rectangle() { }
  virtual unsigned int area() const { return h * w; }
  virtual bool isSquare() const { return false; }
};

class Square : public Rectangle
{
public:
  Square(unsigned int edge) : Rectangle(edge, edge) { }

  // no need to override "area"
  virtual bool isSquare() const { return true; }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...