【问题标题】:How to create a template class with an array of any type and set values to them?如何使用任何类型的数组创建模板类并为其设置值?
【发布时间】:2018-01-16 16:48:27
【问题描述】:

我正在开发一个名为 Collection 的模板类,它只有和数组作为模板类的私有成员。我还需要实现其他类,但现在我正在研究其中一个类,称为 Hotel。

我应该创建一个像template class Type,int p_ 这样的模板,所以当我在主函数中调用Collection Hotel,5 h; 时,它应该创建一个酒店类型的数组,对吗?但是当我尝试这样做时,它只会创建一个酒店类型的对象并调用它的默认构造函数。

我可以使用一些建议来设置对象的值。酒店类有char* HotelName;int numRooms,openedYear,catagoryHotel

template <class Type,int p>
class Collection
{
private:
    Type* niz;
    int n;//added this just in case
public:
    Collection();
    ~Collection();
    bool Find(Type t);//checks if the t is in the array with operator!=
    void Arrange();//arranges the array
    void Reverse();//swithces the first memmber of array to the last and the second to p-2
    void Set(int i,Type t);//should set t to the niz[i]
    void SaveElement(int i, char* Dat);//this is for saving in a file
    void ReedElement(char*Dat);//this is for printing on the screan from a file
    //bool operator!=(Type& t,Type& a);//visual studio is telling me 2 many arguments,dont know why

};
class Hotel
{
private:
    char*HotelName;
    int numRooms, openedYear,catagoryHotel;
public:
    Hotel();
    ~Hotel();
    void SetHotel();
    //bool operator <=(Hotel& h1, Hotel& h2);this for some reason doesnt work also
};
//In my constructor for Collection i typed
template<class Type, int p>
inline Collection<Type, p>::Collection()
{
    n = p;
    niz = new Type[n];
}
//in the constructor for Hotel() i typed
Hotel::Hotel()
{
    HotelName = "Undenfined";
    catagoryHotel = 0;//how much stars it has
    openedyear = 0;
    numRooms = 0;
}

这是我为酒店输入的所有内容,在我弄清楚之前我不想再继续下去了。

【问题讨论】:

  • 请注意缩进代码,使其尽可能可读。扁平缩进(即根本没有缩进)使得很难准确地知道一个块的开始位置和结束位置。
  • 我想创建一个像“template class Type,int p”这样的模板,所以当我打电话给 Collection Hotel,5 h;在主函数中,它应该创建一个酒店类型的数组,对吗? 不,这是不正确的。请阅读a good book打下坚实的基础。
  • 我还是这个网站的新手,对不起
  • 我不清楚你到底在问什么,或者你遇到了什么问题。你有编译错误吗?你有运行时错误吗?你没有得到预期的结果吗?
  • 无法编译 - 有几个错别字。 opensyear vs opensYear,“char* HotelName”可能应该是“std::string HotelName”可能应该使用酒店初始化列表。

标签: c++ arrays templates


【解决方案1】:

在查看您的代码之后,并在查看您的代码时从设计过程的角度来看;您应该将您的 Collection class templateHotel class 和其他 classes 分隔到单独的模块 - 文件中。

在您的Hotel 对象中,您有一个默认构造函数并且它有私有成员,但是您无法设置这些值。你可以定义一个构造函数来设置它的成员,也可以有一个函数来做这件事,看起来你做了SetHotel(),但它不需要任何parameters

在您的class template 中,而不是使用raw T pointer,您有多种选择。

  • 你可以有一个container 类型为T {vector, list, etc.} 并且如果你的集合比较小,就直接包含对象,例如:numTypes &lt;= 100000。否则你可以使用堆:见下文。
  • 或者您可以使用shared_ptrunique_ptr 的智能指针向量,在这种情况下shared_ptr 会更合适。这使得内存管理更加简洁,更易于阅读,内存泄漏、悬空指针、无效引用等的可能性更小。

上述课程的示例:


Hotel.h

#ifndef HOTEL_H
#define HOTEL_H

#include <string>

class Hotel {
private:
    // char* HotelName; // replace with std::string
    std::string hotelName_;
    unsigned numRooms_; // changed to unsigned since you would not have negative rooms. 
    unsigned openingYear_; // same as above for unsigned as well as made the variable name make more sense.
    unsigned hotelRating_; // same as above for unsigned, also changed name to rating

public:
    Hotel(); // default constructor okay
    Hotel( const std::string& hotelName, unsigned numRooms, unsigned rating );
    ~Hotel() = default; // default destructor okay: set to default - not managing memory via new & delete

    void setHotel( const std::string& hotelName, unsigned numRooms, unsigned rating );
};

#endif // !HOTEL_H

Hotel.cpp

#include "Hotel.h"

// Hotel() - Default Constructor - Enables you to instantiate an "empty" object
Hotel::Hotel() : 
hotelName_( "Undefined" ),
numRooms_( 0 ),
rating_( 0 ) {
}

// Hotel( ... ) - User Defined - Enables you to instantiate an object that requires known data
Hotel::Hotel( const std::string& hotelName, unsigned numRooms, unsigned rating ) :
hotelName_( hotelName ),
numRooms_( numRooms ),
raiting_( rating ) {
}

// ~Hotel() - Default Destructor - Defaulted in header file

void Hotel::setHotel( const std::string& hotelName, unsigned numRooms, unsigned rating ) {
    hotelName_ = hotelName;
    numRooms_  = numRooms;
    rating_    = rating;
}

Collection.h

#ifndef COLLECTION_H
#define COLLECTION_H

#include <vector>
#include <memory>

template<class Type, int p>
class Collection {
private:
    std::vector<std::shared_ptr<Type>> collection_;
    int n;//added this just in case
public:
    Collection();
    ~Collection();

    bool find( Type t ); 
    void arrange(); // without any parameters how do you plan to arrange your container?
    void reverse(); 
    // void set( int i, Type t ); // since I decided to use std::vector<...> changed this to addElement( Type t );
    void addElement( Type t );
    void saveElement( int i, const std::string& dat );
    void readElement( const std::string& dat ); 
    //bool operator!=(Type& t,Type& a); //visual studio is telling me 2 many arguments,dont know why    
};

template<class Type, int p>
inline Collection<Type, p>::Collection() {
    // don't need to do anything since you have
    // an empty std::vector<std::shared_ptr<Type>> 
}

template<class Type, int p>
inline Collection<Type, p>::addElement( Type t ) {
    collection_.emplace_back( new Type( t ) ); // Psudeo
}

#endif // !COLLECTION_H

这只是从设计的角度来看,至于您的overloaded operators 的问题,您应该在单独的问题中询问它们。

【讨论】:

  • 感谢您的帮助,顺便说一句,我确实将它们输入到单独的文件中。我会尝试看看是否有任何变化。
猜你喜欢
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多