2013-04-13 35 views
1

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

从那里我需要通过引用来调用这些整数的方法。在这个方法里面,我应该动态地将整数转换为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 
} 

这是知道了,以后还是我做错了什么?
你对我在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; 
} 
+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 
} 

最后,因为模板定义必须在头一个yway,你甚至可以写在类定义内的一切是这样的:

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

为您后者的问题:

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数组,我不认为你真的需要模板。除非你想在未来将双倍数,浮点数和其他类型转换为char*。我没有看到所有问题,所以可能还有其他问题。