【问题标题】:Declaring an array of objects of a class when a (non) default constructor is (not) defined?在(未)定义(非)默认构造函数时声明类的对象数组?
【发布时间】:2019-05-06 14:09:00
【问题描述】:

假设我在 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++ 提供了一个内置的基本构造函数。但是如果我传递参数,它应该会抛出一个错误。

假设我声明了一个此类对象的数组,即

我的类数组我的类[100];

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

我的理解是否在任何地方都不正确?还有在那些我想不通的情况下会发生什么?

【问题讨论】:

  • 你使用什么编程语言?
  • 如果MyClass 没有默认构造函数(可以不带参数调用的构造函数),那么MyClass Obj; 将无法编译。
  • 但是如果它有一个带有默认参数的非默认构造函数,它应该可以编译,对吧?
  • 根据定义,可以不带参数调用的构造函数(无论是因为它没有参数还是因为所有参数都有默认值)是默认构造函数。鉴于此,我不确定您所说的 “具有默认参数的非默认构造函数”是什么意思
  • 无论如何,如果MyClass Obj; 编译,那么MyClass ArrayMyClass[100]; 也会编译。在第一种情况下被调用的同一个构造函数,在第二种情况下也会被调用一百次。

标签: c++ arrays oop default-constructor


【解决方案1】:

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

案例 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;
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 2020-11-25
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多