模板类的构造函数在使用 new 关键字时调用类型构造函数

Constructor of template class calls type constructor when new keyword is used

本文关键字:构造函数 关键字 new 类型 调用      更新时间:2023-10-16

我正在开始一个模板LinkedList类的基本实现。当我单独使用 g++ 编译头文件时,没有问题。但是,当我尝试使用另一个实现某种类型的链表的类进行编译时,它会给我一个错误。它似乎想要编译节点类型的对象。为什么会这样做?构造函数不调用模板类型的构造函数。

我将发布所有相关的头文件。可能有无关的代码,但我想展示正在使用的内容。我将发布错误消息,然后是链表实现,然后是使用链表的类,然后是错误提到的 ParkingLot 构造函数。

以下是错误消息:

LinkedList.h: In instantiation of ‘Node<T>::Node(T) [with T = ParkingLot]’:
LinkedList.h:46:9:   required from ‘void LinkedList<Type>::addNode(Type) [with Type = ParkingLot]’
Decal.h:20:28:   required from here
LinkedList.h:13:16: error: no matching function for call to ‘ParkingLot::ParkingLot()’
  Node(T input) {
                ^
LinkedList.h:13:16: note: candidates are:
In file included from Decal.h:2:0,
                 from test.cpp:3:
ParkingLot.h:28:2: note: ParkingLot::ParkingLot(int, std::string, int, int, int, int)
  ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
  ^
ParkingLot.h:28:2: note:   candidate expects 6 arguments, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(const ParkingLot&)
 class ParkingLot {
       ^
ParkingLot.h:7:7: note:   candidate expects 1 argument, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(ParkingLot&&)
ParkingLot.h:7:7: note:   candidate expects 1 argument, 0 provided

谁能提供一些建议?我不知道为什么当我只想构造一个 ParkingLot 类型的节点时,它会尝试构造一个 ParkingLot 对象。

以下是实现:

#include <iostream>
template <typename T> class Node {
public:
/*Class variables*/
T data;
Node* next;
/*Class constructors*/
Node(T input) {
    data = input;
    next = NULL;
}
};

template <typename Type> class LinkedList {
public:
/*Class variables*/
Node<Type>* head;
/*Class constructor*/
LinkedList(){
    head = NULL;
}
/*Class Methods*/ 
void addNode(Type value) {
    Node<Type>* p;
    if (head == NULL) {
        head = new Node<Type>(value); ********ERROR
    }
    else {
        p = head;
        while (p->next != NULL){
            p = p->next;
        }
        p->next = new Node<Type>(value); ************ERROR
    }
}
//Check to see if linked list contains specified value
bool contains(Type value) {
    Node<Type>* search;
    if ( head != NULL) {
        search = head;
    }
    else {
        return false;
    }
    while(search->next != NULL) {
        if (search->data.compare(value)) {
            return true;
        }
        search = search->next;
    }

    if (search->next == NULL && search->data.compare(value)) {
        return true;
    }
    else {
        return false;           
    }
}
void print(){
    Node<Type>* p;
    p = head;
    while (p != NULL) {
        std::cout << p->data.print() << " ";
        p = p->next;
    }
    std::cout << "n";
}
};

这是来自 Decal 类的代码,它只是尝试使用停车场类型的链表。它以这种方式设计,以便一定数量的停车场对应于一种贴花。

#include <string>
#include "ParkingLot.h"
#include "LinkedList.h"
class Decal {
//Class Variables
private:
LinkedList <ParkingLot> decal_list;
std::string decal_name;
//Class Methods
public:
Decal(std::string name) {
    decal_name = name;
}
void addLot(ParkingLot newLot) {
    decal_list.addNode(newLot);
}
bool hasLot(ParkingLot searchLot) {
    return decal_list.contains(searchLot);
}

};

最后,我包含了停车场构造函数以供参考。它具有名称和位置 x,y 以及用于填充其空间的其他参数。

    ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
    //Generate bool array for parking spaces
    lot_capacity = num_spaces;
    for (int i =0; i<lot_capacity; i++) {
        parking_lot[i] = true;
    }
    /*Determine if lot is full or not, and if not generate random full spaces*/
    //Assigning percentages to corresponding variable
    sp_generator  = randSpacesPercent;
    lot_generator = randLotPercent;
    //Make lot full or not based on percentage
    generateLot(lot_generator);
    //If lot is not full, assign certain percentage of spots as full/empty
    if (isFull() == false) {
        generateSpaces(sp_generator);
    }
    //Assing other vars
    parking_lot_name = name;
    x_locat = x;
    y_locat = y;
}

感谢您提供的任何帮助!

Node的 ctor 调用了类型 T 的默认 ctor,然后将其分配给 ctor 的主体中。如果类型 T 没有默认 ctor,则编译将失败。

最好在构造函数中使用初始值设定项列表而不是赋值,它将调用类型 T 的复制 ctor。在大多数情况下,它可以提高性能。

Node(T input) : data(input), next(NULL) {}

顺便说一句:参数input最好使用 const 引用,它可以避免一次复制。

Node(const T& input) : data(input), next(NULL) {}