首页 > 解决方案 > 在(未)定义(非)默认构造函数时声明类的对象数组?

问题描述

假设我在 C++ 中定义了一个类 MyClass,并希望创建一个包含 100 个此类对象的数组,即 ArrayMyClass。

在此之前,假设我声明了 MyClass 的单个对象,即

我的类对象;

让我们来看以下案例:

  1. MyClass 只有一个默认构造函数
  2. MyClass 只有一个没有默认参数的非默认构造函数
  3. MyClass 只有一个带默认参数的非默认构造函数
  4. MyClass 有默认和非默认构造函数,但后者没有默认参数
  5. MyClass 有默认和非默认构造函数,但后者有默认参数
  6. MyClass 有 2 个非默认构造函数,其中一个有默认值,另一个没有默认参数
  7. MyClass 有一个默认构造函数和两个非默认构造函数,一个有默认参数,另一个没有默认参数。
  8. MyClass 没有定义构造函数。

我试图弄清楚在哪些情况下将声明对象以及调用哪个构造函数。

我的理解是传递给对象的参数类型决定了调用哪个构造函数。所以,

  1. 在情况 1 中,如果未传递任何参数,则应声明对象。如果传递了参数,它应该抛出一个错误。
  2. 在情况 2 中,仅当我传递正确类型的参数时才应声明对象。如果我不传递任何参数或传递错误类型/数量的参数,它应该会抛出错误。
  3. 如果我传递了正确的类型/数量的参数,但如果我没有传递任何参数,则应该声明对象。只有当参数的类型/数量不正确时才会抛出错误。
  4. 如果没有传递参数,则调用默认构造函数。如果传递了正确的参数,则调用非默认构造函数。
  5. 在我传递正确参数的情况下,将调用非默认构造函数。我很困惑当你不传递参数时会发生什么。
  6. 在这种情况下,如果我不传递任何参数,则应该调用具有默认参数的非默认构造函数。我不确定传递参数时会发生什么。是不是一个类不能有2个具有相同类型/参数数量的构造函数?
  7. 这个案例看起来与案例 5 相似,我也有同样的困惑。
  8. 在这种情况下,如果没有传递参数,我假设 C++ 提供了一个内置的裸骨构造函数。但是如果我传递参数,它应该会抛出一个错误。

假设我声明了一个这样的对象数组,即

我的类 ArrayMyClass[100];

对于这个声明,据我了解,我对仅声明一个对象的那 8 种情况有相同的推论。

我的理解在任何地方都不正确吗?在那些我无法弄清楚的情况下会发生什么?

标签: c++arraysoopdefault-constructor

解决方案


首先,一个类不能有两个具有相同签名(相同名称和相同数量+参数类型)的构造函数或函数。

案例 1-4:您对案例 1-4 的假设是正确的。

案例 5:您对案例 5 的假设的第一部分也是正确的。至于你关于不传递参数时会发生什么的问题,你会得到“重载 YOURCLASSNAME() 的调用不明确。看看下面的代码:

#include <iostream>
using namespace std;

class Box {
    public:
    int height, width, depth;
    Box() {}

    Box(int h=2, int w=3, int d=4) {
        height=h;
        width=w;
        depth=d;
    }
};

int main()
{
    Box b;
    return 0;
}

此代码生成error: call of overloaded 'Box()' is ambiguous并且构建失败。

案例 6.正如我之前所说,一个类不能有两个签名相同的构造函数。因此,代码将无法构建。以下代码将无法正确编译。

#include <iostream>
using namespace std;

class Box {
    public:
    int height, width, depth;
    Box(int h, int w, int d) {
        height=h;
        width=w;
        depth=d;
    }

    Box(int h=2, int w=3, int d=4) {
        height=h;
        width=w;
        depth=d;
    }
};

int main()
{
    Box b;
    return 0;
}

将生成以下错误消息error: 'Box::Box(int, int, int)' cannot be overloaded

案例 7。您不能有两个具有相同签名的构造函数。如果您有一个默认构造函数和一个带有默认参数的非默认构造函数,并尝试在不传递任何参数的情况下创建一个对象,那么您将得到一个对重载构造函数的模棱两可的调用错误,如案例 5。

案例 8.你的假设是正确的

当您尝试创建对象数组时,同样的规则也适用。如果你试图创建一个Box没有默认构造函数的类数组,你可以像下面的代码那样做:

#include <iostream>
using namespace std;

class Box {
    public:
    int height, width, depth;

    Box(int h, int w, int d) {
        height=h;
        width=w;
        depth=d;
    }
};

int main()
{
    Box box(1,3,2);
    Box b[5] = box;

    for(int i=0; i<5; i++) {
        cout << b[i].height << ' ' << b[i].width << ' ' << b[i].depth << endl;
    }

    return 0;
}

但是,无论如何,你最好还是使用向量来实现这个目的......


推荐阅读