30

我的问题很简单。我们什么时候需要有一个默认构造函数?请参考以下代码:

class Shape
{
    int k;

public:
    Shape(int n) : k(n) {}
    ~Shape() {}
};

class Rect : public Shape
{
    int l;

public:
    Rect(int n): l(n)
    {}      //error C2512: 'Shape' : no appropriate default constructor available

    ~Rect() {}
};
  1. 为什么编译器没有在类 Rect 中隐式生成零参数默认构造函数?

  2. 据我所知,如果一个类(Rect)派生自另一个具有默认构造函数(隐式生成或显式提供)的类(Shape),则默认构造函数应由编译器生成。

4

7 回答 7

29

如果您使用参数创建自己的构造函数,则不会合成默认构造函数。由于您提供Shape了自己的构造函数,因此您现在必须显式写出默认Shape构造函数:

class Shape
{
      int k;

  public:
      Shape() : k(0) {}
      Shape(int n) : k(n) {}
      ~Shape() {}
};

(您可以省略空~Rect() {}定义,因为它们将被综合。)

但是,在我看来,您不想要Shape 的默认构造函数。已正确Rect构建Shape基础:

class Shape
{
      int area; // I've had to guess at what this member means. What is "k"?!

  public:
      Shape(const int area)
         : area(area)
      {}
};

class Rect : public Shape
{
     int l;
     int w;

  public:
     Rect(const int l, const int w)
        : Shape(l*w)
        , l(l)
        , w(w)
     {}
};

另请注意,此示例经常被引用为滥用 OO。考虑一下你是否真的需要在这里继承。

于 2011-03-31T11:21:00.800 回答
12

只有在没有定义其他构造函数的情况下,编译器才会自动生成默认构造函数。不管有没有继承。

而且你还需要通过调用来构造你的基类:

Rect( int n ) : Shape( n ), l(n)
{
}
于 2011-03-31T11:17:55.323 回答
2

当且仅当您没有显式声明任何 ctor 时,编译器才会定义默认 ctor。

请注意,重要的是声明构造函数,而不一定要定义它。例如,声明一个私有 ctor 并且从不定义它是相当常见的,以防止编译器隐式定义任何其他 ctor。

编辑:另请注意,C++11 具有=default处理像您这样的情况的语法。

于 2011-03-31T11:18:39.660 回答
2

有关 C++ WRT 构造函数的完整行为,请参阅此:http ://en.wikipedia.org/wiki/Default_constructor

简单的答案是,如果您指定构造函数,编译器不会为您创建默认构造函数。

这条规则也适用于 Java。

于 2011-03-31T11:20:20.147 回答
1

如果您没有定义任何构造函数,编译器会生成默认构造函数。但是,如果您定义了任何带参数的构造函数。编译器将使用该构造函数,并且不会生成具有零参数的默认构造函数。

于 2011-03-31T11:25:02.293 回答
0

当您为 Shape 定义一个期望整数的构造函数时,您已经通过这样做覆盖了默认构造函数。因此,如果您扩展 Shape,您必须将一个整数值传递给超类。

于 2011-03-31T11:23:01.933 回答
0

仅当您没有定义任何其他构造函数时才会生成默认构造函数。

假设,如果您需要在类中进行一些特殊的初始化,默认构造函数不会做正确的事情。

于 2011-03-31T11:18:30.897 回答