模板类析构函数

时间:2011-09-30 06:29:32

标签: c++

我正在尝试用c ++创建一个简单的模板类。我一直在尝试编译以下内容,但我只收到编译错误。这是代码:

#include <stdlib.h>
#include <stdio.h>

template<int size>
class array {
public:
    int len;
    int data[size];
    array(void) : len(size) {}
    virtual ~array(void) {}
};

int main() {
    array<3> a;
    for (int i=0; i < a.len; ++i) {
        a.data[i] = i;
        printf("%d\n", a.data[i]);
    }
    return 0;
}

这是错误g ++ - 4.2.1给了我:

Undefined symbols:
  "__Unwind_Resume", referenced from:
      _main in ccaYob9x.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

如果我们注释掉析构函数的行,那么代码就会按照它应该进行编译,它会给出一个数字0,1,2的列表。

在了解模板基类如何工作之后,我的最终目标是创建专门的模板类。我想创建一个多维数组,但我希望专门针对维度为1,2和3时的情况。我主要希望能够为这些情况重载operator()。在任何情况下,使用这样的模板类可以省去在尺寸为1,2和3时动态分配内存的麻烦。有人知道如何更改代码以动态分配内存吗?这样做将要求您定义析构函数,这是我目前面临的问题。

修改

我不熟悉模板专业化。当size = 1,2和3时,有人知道如何制作专门的模板以获得数据的静态内存并且默认情况下具有动态内存吗?

编辑2:

由于我的g ++编译器,我似乎遇到了麻烦。有没有人看到任何与此有关:

g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~6/src/configure --disable-checking --enable-  werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple- darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)

编辑3:

我的g ++版本出现了问题。我只是在同一台机器上使用g ++ 4.0并使用macports版本g ++ - mp-4.3进行了尝试,它运行正常。我想是时候升级到下一个版本了。感谢您的回答和提示。

2 个答案:

答案 0 :(得分:3)

试试这个:

template<int size>
class array {
public:
    int len;
    int *data;
    array();
    virtual ~array(void);
};

// 1 dimension specialized array 
template <>
array<1>::array() : len(1)
{
    data = new int;
}

template <>
array<1>::~array()
{
    delete data;
}

template <int size>
array<size>::array() : len(size)
{
data = new int[size];
} 

template <int size>
array<size>::~array()
{
delete [] data;
}

int main(int, char)
{
    array<3> a;
    for (int i=0; i < a.len; ++i) {
        a.data[i] = i;
        printf("%d\n", a.data[i]);
    }

    array<1> b;
    for (int i=0; i < b.len; ++i) {
        b.data[i] = i;
        printf("%d\n", b.data[i]);
    }

    return 0;
}

使用g ++,你不会有编译错误。您可以为每个不同的数组大小定义专门的operator()而不会出现问题,例如构造函数和析构函数接缝。

答案 1 :(得分:1)

这与问题没有严格关系,但是让我给你一些关于你的代码的提示。

首先:决定是否要使用C或C ++。模板是C ++,但你是“编码为C程序员”。并不是说这本身就很糟糕,不仅仅是出于背景。 (使用iostream,而不是stdlib.hstdio.h,请勿使用function(void),而只使用function())。 可能不是你的情况,但检查你的源码没有“C”扩展名(这可能欺骗编译器)并使用g ++(而不是gcc)作为命令(你将链接的库是不同的)

第二:注意变量和常量的使用:inst size作为模板参数,当实例化时是常量。保持len变量毫无头绪(在您的设计中,数组大小无法更改):static const int len = size就是您所需要的。

第三:如果你真的想测试,不要使用单个for循环来分配和读取值:这会让你在索引被误用的情况下完全失明:而不是a.data[i]尝试错误的a.data[0],你会得到完全相同的输出。使用循环填充数组,然后使用另一个循环来读取它。

第四:在C ++中,范围很重要:保持打开和关闭大括号{}。这可能听起来很迂腐,但多次救了我......