【问题标题】:Assigning value to a constant dynamically-sized array in the constructor of a class在类的构造函数中为常量动态大小的数组赋值
【发布时间】:2012-10-01 07:29:03
【问题描述】:
  • 我有两个班级,A 和 B
  • B 类有一个私有成员变量,它是一个动态常量 对象 A 的大小数组
  • B 类的构造函数之一将采用常量引用 一个 A 类对象,用于设置 B 类中的数组

B 类:

class B
{
  private:
    const A** theArray;
  public:
    B(const A&);
};

B::B(const A& newA)
  : theArray(newA) //<-- ??
{
}

当我尝试编译程序时,我收到一条错误消息“无法从 'const A' 转换为 'const A **'”

我如何将一个对象传递到成员初始化器列表中,以便我可以从中创建一个数组?

编辑 1: 这是一个 comsci 课程作业。我们现在正在学习类,分配让我们为这个特定的类创建三个单独的构造函数(一个复制构造函数;一个用于将新的 A 对象添加到 B 类的“theArray”中;以及一个添加第一个 A 对象的构造函数进入'theArray'(这是有问题的构造函数)。)

这个想法是你调用列表中的第三个构造函数来创建一个对象。然后,如果您想将另一个 A 对象添加到数组中,您将调用第二个构造函数。然后,如果您想要对象的副本,您将使用复制构造函数。

【问题讨论】:

  • 您想将单个对象的引用设置为数组?您不能从单个对象中创建一个数组。如果你不想引用对象,你需要传递一个指向数组的指针。

标签: c++ class constructor constants


【解决方案1】:

当我尝试编译程序时,我收到一条错误消息“无法从 'const A' 转换为 'const A **'”

然后,您必须做的第一件事就是了解编译器错误。编译器在说什么?

B 构造函数中,您使用const A &amp; 类型的给定参数初始化const A ** 类型的成员;它们不是同一类型,这就是编译器抱怨的原因。

那么,如何解决呢?

您必须使B 构造函数采用相同类型的成员变量作为参数。

class B
{
private:
    const A** theArray;
public:
    B(const A**);
};

B::B(const A** newA)
    : theArray(newA) //<-- They're of the same type: no problem.
{
}

但你必须确保类外的调用与构造函数定义相匹配。

但是,我建议修改设计,而不是它,您确定裸指针是您问题的唯一解决方案吗?您必须回答这些问题才能改进class B

  • 动态内存在哪里创建和在哪里销毁?
  • class B 拥有给定A** 的所有权?

如果class B 将成为动态内存的所有者,您必须考虑在class B 内部而不是外部创建和销毁theArray

如果class B不是动态内存的所有者,你必须非常小心内存:theArray指向的内存将在class B之前或之前被销毁?换句话说,可能是一个class B 实例,其内存由theArray 指向已被删除?在这种情况下,智能指针可以提供很好的帮助。

【讨论】:

    【解决方案2】:

    不是在 C++ 中指定动态大小的数组的方式。 你的 B 类应该是:

    class B
    {
        std::vector<A> const theArray;
    public:
        B( A const& initialA )
            : theArray( n, initialA )
        {
        }
    };
    

    这就留下了n(元素的数量)在哪里的问题。 在数组中)来自,以及为什么你要创建一个 所有元素都相同的不可变数组。

    事实上,我很怀疑您是否准确地描述了您正在尝试的内容 去做。您实际上是否想要一个指向A 的指针数组(实际 A 对象位于其他位置,而不是 B 的一部分 目的)?和 A 对象 const (但不是数组 - “a 常量动态大小的数组”是矛盾的)。在这种情况下:

    class B
    {
        std::vector<A const*> theArray;
    public:
        B( A const& initialEntry )
            : theArray( 1, &initialEntry )
        {
        }
    };
    

    然后您可以稍后添加其他条目(始终为 A const* 类型)。

    【讨论】:

    • 这是一个 comsci 课堂作业。我们现在正在学习类,分配让我们为这个特定的类创建三个单独的构造函数(一个复制构造函数;一个用于将新的 A 对象添加到 B 类的“theArray”中;以及一个添加第一个 A 对象的构造函数进入'theArray'(这是有问题的构造函数)。这个想法是你调用列表中的第三个构造函数来创建一个对象。然后,如果你想向数组中添加另一个 A 对象,你将调用第二个构造函数。然后如果你想要一个对象的副本,你可以使用复制构造函数
    • @LoganBesecker 在这种情况下,我的第一个解决方案可能就是想要的(使用n == 1)。当然,这假设A 支持复制。另一方面,练习的目标可能是教你如何在三法则适用时进行编程,在这种情况下,一些动态分配将是有序的。在这种情况下,theArray 的类型应该是A const*,用new A[1] 初始化,然后分配给它的初始值。
    【解决方案3】:

    您没有为指针数组分配任何内存。

    对于构造函数,您应该传递 A 的指针而不是引用。

    【讨论】:

      【解决方案4】:

      当然std::vector&lt;int&gt; 更可取-有关如何使用它,请参阅其他答案。 如果您真的想使用动态数组 - 请记住添加析构函数并复制/移动内容。

      请记住,您需要知道传递给 B(const A&amp;) 的 A 对象是什么。它不能是暂时的。这个 newA 必须与 B 对象一样长。如果它是动态的(由 new 创建) - 您必须知道哪个对象将负责删除它。是B级还是什么?

      无论如何,只是为了显示直接答案:

      在 C++11 中,使用新的 {} 初始化语法非常简单,与 std::vector 相同

      class B
      {
        private:
          const A** theArray;
        public:
          B(const A&);
      };
      
      B::B(const A& newA)
        : theArray(new const A*[some_size] { &newA } ) //<-- ??
      {}
      

      在 C++03 中,需要一个额外的静态方法来创建/初始化动态数组:

      class B
      {
        private:
          const A** theArray;
          static const A** makeArray(const A& a)
          {
             const A** rv = new const A*[some_size]();
             rv[0] = a;
             return rv;
          }
        public:
          B(const A&);
      };
      
      B::B(const A& newA)
        : theArray(makeArray(newA))  //<-- ??
      {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 2016-09-13
        • 2019-07-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多