模板类 - 几个问题

时间:2013-04-13 13:18:01

标签: c++ templates c++11 delegating-constructor

我需要创建两个整数作为参数的构造函数。

从那里我需要通过引用调用这些整数的方法。在这个方法中,我应该将整数动态转换为char*类型(数字数组)。

在构造函数的末尾,我应该有两个char*数组而不是初始整数。

我有点必须这样做,因为另一个类在结构上做同样的事情。并将它们保存到模板属性中。


我是c ++语言的新手,但我的第一个猜测是使用模板。我对这个主题进行了一些研究,发现它应该有效。

我喜欢自己编译整个事情,但是在我的头脑中实现c ++类的混乱产生了很长的编译错误列表。


第一个问题 - 可以使用模板完成吗? 第二个问题,因为我已经自己写了一些东西:

template <class type> class Addition {
   type num_a;
   type num_b;
   void convert(type, type);
public:
   Addition(type, type);
}

template <class type> Addition::Addition(type a, type b) {
   convert(&a, &b);
   num_a = a;
   num_b = b;
}
template <class type> Addition::convert(type *a, type *b) {
   int temp_a = a, temp_b = b;
   a = char[256], b = char[256];
   // converting
}

这是o.k.,还是我做错了什么? 您对我在c ++中实现类的方式有什么建议吗?

为什么我不能用值初始化属性,如:

template <class type> class Addition {
   type outcome = 0;
}

如果不需要在c ++中使用此关键字,我该如何做这样的事情?:

template <class type> Addition::Foo(type a, type b) {
   this->a = a; // a = a;
   this->b = b; // b = b;
}

2 个答案:

答案 0 :(得分:2)

免责声明:我无法判断您确实需要模板来处理您正在做的事情。这取决于您希望Adddition类模板使用的不同类型的数量。如果你只将它用于int,那么这可能会带来不必要的复杂性。你以后总是可以重构(这将是敏捷方法)。

话虽如此,如果你想使用模板,通常的惯例是为模板参数编写T,并在类模板中使用type作为嵌套typedef 。使用typenameclass是一个品味问题,但typename强调内置类型也可以作为参数传递。但请注意,使用模板模板参数,您需要编写

template<template<typename> class U> SomeClass { /* your definition */ };
                            ^^^^^ // <-- NOT typename here 

强调只有类模板可以作为参数传递。

还有一些其他的提示可以提及你的代码会使它无法编译(convert()中缺少返回类型并且在类定义中缺少分号):

template <typename T> 
class Addition 
{
   static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
   T num_a;
   T num_b;
   void convert(T const*, T const*); // by T const*, not T*
public:
   Addition(T const&, T const&); // by T const&, not T
}; // <-- make sure to end class definitions with a semi-colon!

template <typename T> 
Addition::Addition(T const& a, T const& b) 
{
   convert(&a, &b);
   num_a = a;
   num_b = b;
}

template <typename T>
void Addition::convert(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
^^^^ // <-- you forgot the return type
{
   int temp_a = a, temp_b = b;
   a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
   // converting
}

在C ++ 11中,你甚至可以使用委托构造函数(最新的Visual C ++支持,当然还有gcc / Clang)并编写

template <typename T> 
Addition::Addition(T const& a, T const& b) 
:
    Addition(&a, &b) // delegate to the other constructor
{}

template <typename T>
Addition::Addition(T const* a, T const* b) // <-- use T const* if you don't modify the parameters
{
   int temp_a = a, temp_b = b;
   a = char[N], b = char[N]; <-- hardcoded 256 is bad practice, better to keep that in 1 place only
   // converting
}

最后,因为模板定义无论如何都必须在头文件中,你甚至可以在类定义中编写所有内容,如下所示:

template <typename T> 
class Addition 
{
   static const std::size_t N = 256; // are you sure that 256 is all you'll ever need?
   T num_a;
   T num_b;

   Addition(T const*, T const*) // by T const*, not T*
   {
      int temp_a = a, temp_b = b;
      a = char[N], b = char[N]; 
      // converting
   }
public:
   Addition(T const&, T const&) // by T const&, not T
   :
       Addition(&a, &b) // delegate to the other constructor
   {} 
}; // <-- make sure to end class definitions with a semi-colon!

这使您免于繁琐地编写所有成员函数的声明和定义。对于简短和甜蜜的课程(无论如何你应该努力),这是编写模板的首选方式,但是对于很长的定义,你可能想要将声明和定义分开。

最后,正如@tacp所解释的那样,您确实需要使用this->a来消除函数参数中的类数据成员的歧义。出于这个原因,人们经常使用尾随下划线或m_前缀来编写数据成员。

答案 1 :(得分:1)

对于后面的问题:

template <class type> class Addition {
  //type outcome = 0; 
  //^^^^you have to call default constructor of type
  type outcome = type();
}

最好使用typename进行约定,使用class也可以。

template <class type> Addition::Foo(type a, type b) {
   this->a = a; // a = a;
   this->b = b; // b = b;
}

如果传递的参数和成员具有相同的名称,则需要使用this。你做不到

a =a;
b =b;

由于a,b位于本地范围内,但this->a表示类成员a

由于您总是希望将整数转换为char数组,因此我认为您不需要模板。除非您希望将来将double,float和其他类型转换为char*。我没有看过所有问题,所以可能还有其他问题。