【问题标题】:C++ - Calling the non default constructor in a nested template instantiationC++ - 在嵌套模板实例化中调用非默认构造函数
【发布时间】:2014-05-13 00:06:06
【问题描述】:

我目前正在为 FreeCell 实现实例化一组卡片堆栈。 Array、Stack 和 Card 类都是我自己创建的,Stack 和 Array 类都是模板化的。

Array<StackRA<Card>> * hometemp = new Array<StackRA<Card>>(4);

当此代码运行时,它会按预期实例化一个大小为 4 的 Array,但会调用 Stack 上的默认构造函数,我需要将其实例化为大小为 13。

我尝试了以下方法:

Array<StackRA<Card>> * hometemp = new Array<StackRA<Card>(13)>(4)
Array<StackRA<Card>> * hometemp = new Array<StackRA<Card>13>(4)

Stack的默认构造函数如下:

template <typename T>
StackRA<T>::StackRA() : m_stack()
{
    size = 0;
}

以及我要调用的 1 arg 构造函数

template <typename T>
StackRA<T>::StackRA( int data ) : m_stack( data )
{
    size = data;
}

我在 Google 上试试运气,但它不断引导我访问模板类中的模板资源。任何想法表示赞赏。

编辑:进入我的程序会导致 Array 构造函数

template<class T>
Array<T>::Array(int length, int start_index)
{
    if (length < 0)
    {
        cout << "Length cannot be negative, length has been defaulted to 0\n";
        m_length = 0;
    }
    else
    {
        m_length = length;
        m_start_index = start_index;
        m_array = new T[length];
    }
}

更具体地说,问题在于“m_array = new T[length];”调用 StackRA 默认构造函数。问题仍然存在,如何调用非默认构造函数。我应该在实例化的哪个位置放置我想要传入的尺寸数据?

EDIT2:我已经解决了这个特定实现的问题:

template <typename T>
StackRA<T>::StackRA() : m_stack()
{
    size = 13;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    首先,如果Array 表示一个数组,并且打算像一个数组一样使用,那么您不需要创建指针。您可以将其构造为自动对象:

    Array<StackRA<Card>> hometemp(4);
    

    现在问题在于您所说的以下代码为数组中的每个元素调用默认构造函数:

    m_array = new T[length];
    

    这是真的,将调用默认构造函数,将每个构造函数初始化为T()。在 C++11 之前,无法使用不同的构造函数初始化每个元素,但现在您可以使用初始化列表进行初始化:

    m_array = new T[length] { T(13), T(13), ... };
    

    当然,这对于可变大小的数组(或非常大的数组)来说是不可取的,而且这不是我们的目的。相反,您可以遵循 std::vector 的行为并创建另一个构造函数,将对象复制到数组中的每个元素:

    template <typename T>
    StackRA<T>::StackRA(int size, const T& obj) : size(size), m_stack(/* ... */)
    {
        m_array = new T[size];
        std::fill(m_array, m_array + size, obj);
    }
    

    现在在构造数组时,您可以传递正确的构造函数:

    Array<StackRA<Card>> hometemp(4, StackRA<Card>(13));
    

    【讨论】:

    • 最后一行,你的意思一定是Array&lt;StackRA&lt;Card&gt;&gt; hometemp(4, StackRA&lt;Card&gt;(13));
    【解决方案2】:

    您的Array 有什么特别的地方,所以您不能使用std::vector?使用std::vector,您只需说

    std::vector<StackRA<Card>> * hometemp =
        new std::vector<StackRA<Card>>(4, StackRA<Card>(13));
    

    如果大小总是固定的,最好使用std::array,例如

    std::vector<std::array<Card, 13>> * hometemp =
        new std::vector<std::array<Card, 13>>(4);
    

    std::array<std::array<Card, 13>, 4> * hometemp =
        new std::array<std::array<Card, 13>, 4>();
    

    甚至

    using Stack = std::array<Card, 13>;
    using Deck  = std::array<Stack, 4>;
    Deck *hometemp = new Deck();
    

    如果你想添加功能,你可以简单地将标准库容器封装成你自己的类型。

    此外,您可能会重新考虑使用免费存储,尤其是原始指针:

    Deck hometemp;
    

    如果您坚持自己的实现,您可以查看std::vector constructors 以获得想法。

    【讨论】:

      猜你喜欢
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 2011-03-27
      • 1970-01-01
      • 2016-03-01
      • 2016-06-24
      相关资源
      最近更新 更多