是否可以在C ++中的另一个类的构造函数中声明一个类的对象?

时间:2011-08-01 16:41:20

标签: c++ class constructor

是否可以在c ++的另一个类的构造函数中初始化一个类的对象?我通常只在main()中声明对象,但是我很想知道这是否可行并且是一种好的做法。 “new”和没有“new”运算符的情况有什么影响。它在哪里被摧毁?

e.g。假设一个名称空间和一个带有“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 个答案:

答案 0 :(得分:2)

有什么问题?构造函数只是一个普通的函数,因此您所做的就是声明类型为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; }
};

答案 1 :(得分:2)

关于你的实际问题,是的,这是一个非常好的做法(就B区的构造函数中的A语句而言)。这样可以正常地调用A的析构函数。

但是:关于您发布的代码段,在A&#39的构造函数中分配两个对象是良好做法。如果operator new的{​​{1}}失败,则h将被泄露。如果在其构造函数中抛出异常,则不会调用析构函数。因此,如果w引发w,则不会删除new int

答案 2 :(得分:2)

这是完全没问题的 - 事实上,对象确实在构造函数中创建了所需的东西。您在析构函数中正确释放了它们,因此您没有内存泄漏。

还要注意“对”新“和没有”新“操作符的情况有什么影响。”不是问题。如果它们不是指针(h& w),则在创建类时默认构造它们。您可以初始化非指针对象,但是如果您希望使用这样的初始化列表:

private: 
    int w;
    int h;

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

除非您有理由需要保留对象,否则不应使用new,这样就更有可能导致内存泄漏或分配失败。两者都很好。

-w00te