为返回对的对创建模板类[重复]

Posted

技术标签:

【中文标题】为返回对的对创建模板类[重复]【英文标题】:Creating a template class for a pair that returns a pair [duplicate] 【发布时间】:2017-04-22 22:38:59 【问题描述】:

代码不起作用,我不确定我哪里出错了,任何帮助将不胜感激这是作业的详细信息,通过为名为“Pair”的类编写模板来创建类模板。此类将表示在模板定义中参数化的类型的一对数据成员。例如,您可以有一对整数、一对双精度数等。

/* so I'm trying to implement this driver this is the driver.cpp file and
 * I'm trying to do it with a template class */

int main()

   Pair<char> letters('a', 'd');
   cout << "\nThe first letter is: " << letters.getFirst();
   cout << "\nThe second letter is: " << letters.getSecond();

   cout << endl;
   cin.get();


//this is my .h file code
template <class T>
class Pair

   private:
      T first;
      T second;
   public:
      Pair(const T, const T);
      T getFirst();
      T getSecond();
;

//this is my Pair.cpp
#include "Pair.h"


template<class T>
Pair<T>::Pair(const T first, const T second)

   return first, second;


template<class T>
inline T Pair<T>::getFirst()

   return first;


template<class T>
inline T Pair<T>::getSecond()

   return second;

【问题讨论】:

构造函数不应该返回值,而是将成员变量设置为参数值。当你使用相同的名字时有点棘手...... 代码不工作并没有解释太多。您是否在编译时、运行时看到问题?问题的本质是什么?如果存在编译时问题,则从编译器发布消息。如果存在运行时问题,请发布输出。 离题:推荐阅读Why include guards? 我收到三个错误,说明外部符号无法解析 【参考方案1】:

您的代码存在两个明显的问题。

首先,您只有Pair.h 中的成员函数声明和单独的Pair.cpp 文件中的定义。虽然这适用于常规函数,但它不适用于模板(请参阅 Why can templates only be implemented in the header file?),正如 Guillaume Racicot 在对您的问题的评论中已经提到的那样。

第二个问题是您的构造函数没有初始化Pair 类的数据成员,而是返回您传递给它的第二个参数,即使构造函数不能有返回值。

要解决这个问题,您需要将构造函数的定义更改为

template <typename T>
Pair<T>::Pair(T fst, T snd)
    : firststd::move(fst),
      secondstd::move(snd) 

这里不需要调用std::move,但这是将值移动到变量中的惯用方式。如果你只做firstfst,你最终会制作一个额外的副本而不是移动,这对于intfloat等原始类型来说没什么大不了的,但是如果你要创建一对大对象(例如两个 1000 元素向量),那么这会产生巨大的差异。

应用这两项更改并添加 include guards 后,您应该最终得到一个 Pair.h 文件

#ifndef PAIR_H
#define PAIR_H

template <class T>
class Pair

   private:
      T first;
      T second;
   public:
      Pair(T, T);
      T getFirst();
      T getSecond();
;

template<class T>
Pair<T>::Pair(T fst, T snd)
    : firststd::move(fst),
      secondstd::move(snd)



template<class T>
T Pair<T>::getFirst()

   return first;


template<class T>
T Pair<T>::getSecond()

   return second;

#endif

【讨论】:

这非常有帮助,感谢您花时间写出来。【参考方案2】:

这里是简单的pair.h模板

// Pair.h
// template for a pair of items of arbitrary types

#include <sstream>
using namespace std;

template <typename S, typename T>
class Pair
   
      public:
               Pair();
               Pair(S,T);
               Pair(Pair &);
               ~Pair();
               const Pair &operator=(const Pair &other);

               string toString();

               S* getFirst();
               T* getSecond();
              int getPairCount();

               void setFirst(S);
               void setSecond(T);

      private:
               S *f;
               T *s;
               static int count;

   ;

template <typename S, typename T>
int Pair<S,T>::count=0;

// 0-parameter constructor
template <typename S, typename T>
Pair<S,T>::Pair()
   
      f = NULL;
      s = NULL;
      count++;
   

// 2-param constructor
template <typename S, typename T>
Pair<S,T>::Pair(S x, T y)
   
      f = new S;  *f = x;
      s = new T;  *s = y;
      count++;
   


// get first element in pointer
template <typename S, typename T>
S* Pair<S,T>::getFirst()
   
      if (f!=NULL)
           S *tmp = new S;
            *tmp = *f;
            return tmp;
         
      else
         return NULL;
   

// get second element in pointer
template <typename S, typename T>
T* Pair<S,T>::getSecond()
   
      if (s!=NULL)
         
            T *tmp = new T;
            *tmp = *s;
            return tmp;
         
      else
         return NULL;
   

// set first element
template <typename S, typename T>
void Pair<S,T>::setFirst(S x)
   
      if (f==NULL)
         f = new S;
      *f = x;
   

// set second element
template <typename S, typename T>
void Pair<S,T>::setSecond(T y)
   
      if (s==NULL)
         s = new T;
      *s = y;
   

// make a string representation
template <typename S, typename T>
string Pair<S,T>::toString()
   
      stringstream ss;
      ss<<"(";
      if (f==NULL)
         ss<<"NULL";
      else
         ss<<(*f);
      ss<<",";
      if (s==NULL)
         ss<<"NULL";
      else
         ss<<(*s);
      ss<<")";
      return ss.str();
   

// keep count
template <typename S, typename T>
int Pair<S,T>::getPairCount()
    return count;

//copy constructor
template <typename S, typename T>
Pair<S,T>::Pair(Pair &other)

f = NULL; s = NULL;
    if(other.f != NULL)
    f = new S(*other.f);

    if(other.s != NULL)
    s = new T(*other.s);

    count++;

//destructor

template <typename S, typename T>
Pair<S,T>::~Pair()

    if(f != NULL)
    delete f;

    if(s != NULL)
    delete s;

    f = NULL;
    s = NULL;

    count--;


//deep assignment

template <typename S, typename T>
const Pair<S,T> & Pair<S,T>::operator=(const Pair<S,T> &other)

    if(this != &other)
    
        if(f != NULL)
        delete f;

        if(s != NULL)
        delete s;

        f = NULL; s = NULL;

        if(other.f != NULL)
        f = new S(*other.f);

        if(other.s != NULL)
        s = new T(*other.s);
    
    return *this;

【讨论】:

Eww,指针... LOL,如果您正在使用模板,您应该对指针有所了解。尝试阅读代码,它会有意义 在这种情况下不需要指针。如果你真的想要这些语义,你至少应该使用std::unique_ptrstd::optional (C++17)。 @dirty_feri 为什么在学习拥有原始指针之前不使用简单的好旧值? 你说得好像std::unique_ptr 是一个高级主题。但在现代 C++ 中,使用 newdelete 是一个高级主题,应该避免。【参考方案3】:

构造函数不应该返回任何东西。它的作用是通过作为参数传递的变量来初始化对象。

template<class T>
Pair<T>::Pair(const T fst, const T scd) : first(fst), second(scd)

【讨论】:

通过应用新语法更正

以上是关于为返回对的对创建模板类[重复]的主要内容,如果未能解决你的问题,请参考以下文章

我可以键入检查模板参数吗? (C++)[重复]

每次创建一个新的 RestTemplate 和创建一个返回相同 Rest 模板的单个类之间的权衡

类模板模板类函数模板模板函数

为啥我不能返回对使用模板创建的派生类的 unique_ptr 的引用?

springboot模板项目搭建:Jwt工具类公共返回对象类

模板模式