为返回对的对创建模板类[重复]
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
,你最终会制作一个额外的副本而不是移动,这对于int
或float
等原始类型来说没什么大不了的,但是如果你要创建一对大对象(例如两个 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_ptr
或std::optional
(C++17)。
@dirty_feri 为什么在学习拥有原始指针之前不使用简单的好旧值?
你说得好像std::unique_ptr
是一个高级主题。但在现代 C++ 中,使用 new
和 delete
是一个高级主题,应该避免。【参考方案3】:
构造函数不应该返回任何东西。它的作用是通过作为参数传递的变量来初始化对象。
template<class T>
Pair<T>::Pair(const T fst, const T scd) : first(fst), second(scd)
【讨论】:
通过应用新语法更正以上是关于为返回对的对创建模板类[重复]的主要内容,如果未能解决你的问题,请参考以下文章
每次创建一个新的 RestTemplate 和创建一个返回相同 Rest 模板的单个类之间的权衡
为啥我不能返回对使用模板创建的派生类的 unique_ptr 的引用?