模板类找不到构造函数

Template class can't find constructor

本文关键字:构造函数 找不到      更新时间:2023-10-16

我目前正在处理模板类(我很失落)。我想构建一个可以存储对象的模板类。

这是我的.h文件:

#ifndef STORAGE_H_
#define STORAGE_H_
#include <iostream>
using namespace std;
template<class T,int maxsize>
class Storage
{
    public:
        Storage();
        int getSize();
        T get(int index);
        bool add(T element);
    private:
        T array[maxsize];
        int length;
};
template<class T,int maxsize>
Storage<T,maxsize>::Storage()
  : length(0),// Liste d'initialisation des données membres
{}
template<class T,int maxsize>
int Storage<T,maxsize>::getSize()
{
    return length;
}
template<class T,int maxsize>
T Storage<T,maxsize>::get(int index)
{
    return array[index];
}
template<class T,int maxsize>
bool Storage<T,maxsize>::add(T element)
{
    if (length>=maxsize) return false;
    array[length++]=element;
    return true;
}
#endif /* STORAGE_H_ */

例如,当我处理int时,它工作得很好。但当涉及到我以前制作的其他对象时,它就失败了。在我的.cpp主文件中:

Storage<Pokemon,4> pokemonArray;

它向我发送了以下错误:

no matching function for call to 'Pokemon::Pokemon()'

口袋妖怪是我的一门课。对我来说,这一行意味着它找不到构造函数Pokemon()。

我怎样才能让它工作?

谢谢你们!

以下代码将工作,假设口袋妖怪有一个默认的构造函数:

#include <iostream>
using namespace std;
template<class T,int maxsize>
class Storage
{
    public:
        Storage();
        int getSize();
        T get(int index);
        bool add(T element);
    private:
        T array[maxsize];
        int length;
};
template<class T,int maxsize>
Storage<T,maxsize>::Storage()
  : length(0)
{}
template<class T,int maxsize>
int Storage<T,maxsize>::getSize()
{
    return length;
}
template<class T,int maxsize>
T Storage<T,maxsize>::get(int index)
{
    return array[index];
}
template<class T,int maxsize>
bool Storage<T,maxsize>::add(T element)
{
    if (length>=maxsize) return false;
    array[length++]=element;
    return true;
}
class Pokemon{
    public: Pokemon(){};
};
int main(){
    Storage<Pokemon,4> pokemonArray;
}

请注意,如果没有给定构造函数,编译器将自动生成一个构造函数,代码仍将编译。

class Pokemon{
    //no constructors is still ok
};

默认构造函数由Storage类中的Array隐式调用。你的口袋妖怪类中很可能有一个非平凡的构造函数,这就是问题的根源。也许是这样的:

class Pokemon{
    public: 
    Pokemon(std::string name){
        //....
    }
    //...
};

当你提供一个非平凡的构造函数时,编译器不会隐式添加一个,因此,你要么需要更改你的Storage类,要么给Pokemon类一个默认的构造函数和你当前的构造函数:

class Pokemon{
    public: 
    Pokemon(){}; //<-- needed
    Pokemon(std::string name){ ... }; //<-- optional
};

由于Storage模板化类有一个固定大小的T(即Pokemon对象)数组:

template<class T, int maxsize>
class Storage
{
public:
    Storage();
    int getSize();
    T get(int index);
    bool add(T element);
private:
    T array[maxsize]; // Array
    int length;
};

当您尝试实例化该类的对象时,应该确保Pokemon类有一个可见的默认构造函数来初始化该对象数组。例如,以下内容不起作用:

class Pokemon {
public:
    Pokemon() = delete;
};
int main(void)
{
    Storage<Pokemon, 4> pokemonArray;
    return 0;
}

解决方案:确保类有一个默认的构造函数或更改您的设计(内部存储的智能指针std::vector怎么样?)

您的错误很简单:

您正在使用初始化的存储。

使用未初始化的存储来存储这些成员,就像使用匿名联合一样
由于您已经接管了所包含的T元素的生命周期管理,因此需要编写自己的复制ctor、移动ctor、复制赋值、移动tor和析构函数。

另一种选择是重新使用一个标准容器,该容器已经为您提供了动态存储,但看起来您想要构建自己的容器并避免堆。

或者,你知道,通过给它们一个默认的ctor来确保你的类型是默认可构造的。