根据运行时创建一个类型的数组

时间:2011-10-26 20:15:00

标签: c++

...是我想做的。我有以下代码:

... 
    int len = 0; 
    char c; 
    bool fp = false;

    while (infile.good()) {
            c = infile.get();
            if (c == '\n') ++len;
            else if (c == '.') fp = true;
    }  

    if (fp == true){
            float Ai[N];
            float *Ao = new float [len];
    } else {
            int Ai[N];
            int *Ao = new int [len];
    }  

    for (int i=0; i<L; ++i){
            for (int j=0; j<N; ++j) infile >> Ai[j];
            Ao[i] = findmax(Ai);
    }
...

如果在文件中检测到小数点,或者如果没有在整数中检测到小数点,则应该使数组超出双精度数。

我没有检查第一个循环,因为我没有得到它编译:

warning: unused variable ‘Ai’                                                         
warning: unused variable ‘Ao’
warning: unused variable ‘Ai’
warning: unused variable ‘Ao’
error: ‘Ai’ was not declared in this scope
error: ‘Ao’ was not declared in this scope

我想我对如何处理这个任务有一个基本问题,而不仅仅是一个简单的错误。

那么,出了什么问题以及如何从一开始就把它做好?

4 个答案:

答案 0 :(得分:3)

编辑:    如上所述,您的编译器错误来自Ao和Ai声明的范围与您尝试使用它的范围不同。


这是模板真正方便的地方。

template<typename T>
T *findMaxes(inFile)
{
    T Ai[N];
    T *Ao = new T[len];

    for (int i = 0; i < L; ++i)
    {
        for (int j = 0; j < N; ++j)
            infile >> Ai[j];
        Ao[i] = findmax(Ai);
    }

    return Ao;
}




int len = 0; 
char c; 
bool fp = false;

while (infile.good()) {
        c = infile.get();
        if (c == '\n') ++len;
        else if (c == '.') fp = true;
}  

if (fp)
{
    float *Ao = findMaxes<float>(inFile);

    // Do stuff with the floating point array
}
else
{
    int *Ao = findMaxes<int>(inFile);

    // Do stuff with the int array
}

答案 1 :(得分:3)

简短回答:你不能这样做。

C ++是一种静态类型语言,这意味着您必须在编译时(即编写代码时)决定变量的类型。您不能说“声明x类型为get_type_from_user()

使用基于继承的多态性,您可以通过基类引用来处理一些设置,但实际的实例化类型是在运行时确定的。我想,这对你的设置来说几乎肯定是有点过分了,但这是在C ++中处理运行时依赖于细节的标准方法。但是,这不适用于原始类型,它们是类型的

这是一个天真的,类型擦除的矫枉过正的例子:

class NumberImpl;

class Number
{
  NumberImpl * pNum;
public:
  explicit Number(int n) : pNum(new NumberInteger(n)) { }
  explicit Number(double d) : pNum(new NumberDouble(d)) { }
  // ..
};

class NumberImpl { /* ... common implementation interface here ... */ }

class NumberInteger : public NumberImpl
{
  int n;
public:
  NumberInteger(int m) : n(m) { }
  // ...
};

// and so forth

这种类型的删除boost.anyshared_ptr使用,它有一些优点。你是否需要它取决于你(但答案是“不”),而你可能只喜欢一种常见的数字类型。如果你使它long double,你通常会得到64位的积分精度,加上吨的比例范围。

答案 2 :(得分:1)

你的问题在于范围..如果你在if块中声明一个变量,它只会存在于那个块中。当你进入最后的循环时,Ao不再存在。你可以试试这个:

if (fp == true)
{
    float Ai[N];
    float *Ao = new float [len];
    for (int i=0; i<L; ++i)
    {
        for (int j=0; j<N; ++j) infile >> Ai[j];
        Ao[i] = findmax(Ai);
    }
}
else 
{
    int Ai[N];
    int *Ao = new int [len];
    for (int i=0; i<L; ++i)
    {
        for (int j=0; j<N; ++j) infile >> Ai[j];
        Ao[i] = findmax(Ai);
    }
}  

答案 3 :(得分:0)

你对这里的根本问题是正确的。 You Ai变量在结束“}”时超出范围。因此,您不能再使用它们了。这也解释了警告,因为你永远不会在它们消失之前使用这些变量。

C ++是静态类型的,因此您不能只在运行时更改变量的类型。

您可以查看联合将浮点数或整数放入变量中。接近C ++的方法可能涉及继承。但如果只有这两种情况,你也可以复制代码(鸭子)。