【问题标题】:Default size of an int variable, when an object is created?创建对象时 int 变量的默认大小?
【发布时间】:2021-09-19 13:35:05
【问题描述】:
class Vect {
    public:
        Vect(int n);
        ~Vect();
        Vect(const Vect& original);
    private:
        int* data;
        int size;
};

Vect::Vect(int n) {
     size = n;
     data = new int[n];
}

Vect::~Vect() {
    delete [] data;
}

Vect::Vect(const Vect& original) {
    size = original.size;
    data = new int[size];

    for (int i = 0; i < size; ++i) {
        data[i] = original.data[i];
    }
}

#include <bits/stdc++.h>

using namespace std;

int main(void) {
    Vect a(100);
    Vect b = a;
    Vect c;
    c = a;
    return 0;
}

我现在有一个 Vect 类,在 main 中我创建了一个变量 c 保存的 Vect 对象,c.size 的默认大小是多少? 或者它不会有任何默认值? 如果它没有默认值,那么 b 怎么会有 100(因为 a.size 现在等于 b.size)?

【问题讨论】:

  • 由于没有默认构造函数,Vect 的实例无法为其任何数据成员设置某种默认值。由于没有匹配的函数调用,代码将无法编译。
  • 您的意思是“int 变量的默认值”吗?
  • 非类成员(如intint *)没有默认值。如果它们未初始化,则它们具有不确定的值,并且使用这些值会导致未定义的行为。
  • 即使添加了默认构造函数,这段代码仍然不符合三规则,因为c = a; 是复制分配,不是用户定义的,因此是默认提供的(即成员副本,最终会导致分配后潜在的内存泄漏和销毁时的双重删除)。
  • 关于不相关的问题,请阅读Why should I not #include <bits/stdc++.h>?Why is “using namespace std;” considered bad practice? 在更相关的说明中,请获取some good books 阅读并了解有关构造函数和“默认值”的所有详细信息想知道。

标签: c++ class oop gcc g++


【解决方案1】:

回答您的问题:Vect::size 没有默认值,除非您在类声明中提供默认值,例如

int size = 0;

如果你不初始化Vect::size,你会招致undefined behavior

另外,这段代码有很多问题,实际上并不能编译。

基本问题:

  • Vect 没有无参数的构造函数,也没有隐式声明default constructor,因为你定义了Vect::Vect(int n)。因此,Vect c; 行无法编译。

  • 代码c = a 不会调用您的复制构造函数Vect::Vect(const Vect&amp; original),因为变量c 已经存在(假设您已经解决了上述问题)。相反,它确实调用了隐式定义的copy assignment operator,您没有显式定义它。然而,这只是复制成员变量,因此它没有“正确”的逻辑,因为在这样的复制之后,c.dataa.data 都指向同一内存区域。它们不是“副本”,因此当ac 超出范围时,分配的内存将被释放两次(程序崩溃)。 您需要定义一个正确的复制赋值运算符Vect::operator=

其他要点:

【讨论】:

    【解决方案2】:

    c.size 的默认大小是多少??

    没有默认值,除非您提供一个。如果你想覆盖它,你应该有一个默认构造函数(否则使用未初始化的变量是未定义的行为)。

    例如:

    Vect::Vect() : data(nullptr), size(0)
    {}
    

    如果它没有默认值,那么b 怎么会有100

    实际上,当你写Vect b = a;时,它相当于Vect b(a);。换句话说,复制构造函数被调用(这是复制初始化)。

    但是,当你写的时候:

    Vect c;
    c = a;
    

    这是一个复制作业。而且您没有提供一个问题,因为您需要处理 data 成员的动态分配(防止自分配,如果不是 nullptr 则取消分配,然后使用新内容重新分配)等等...
    您应该为 Vect 类定义 operator=() 以使您的程序具有良好的格式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      • 2012-09-26
      • 2017-05-06
      • 1970-01-01
      • 2020-04-09
      • 1970-01-01
      相关资源
      最近更新 更多