在main()中为通用模板类选择数据类型

时间:2012-12-03 03:14:09

标签: c++ arrays templates generics dynamic

因此我被要求编写一个简单的矢量模板,我相信我已经正确地编写了类,在我们的教科书(Savitch)中查看了一些通用列表的例子。现在我试图通过让用户选择数据类型来调用main()中的类。我在声明标识符list1后遇到了问题。我想在使用if语句切换数据类型后能够使用相同的标识符。但是,我不认为我的if语句正文中的语法是正确的,因为list1已经声明了。在java中我一直认为在声明一个类之后你可以随时调用它的construtor,但是我不知道如何在C ++中这样做。

#include <iostream>
using namespace std;

template <class T>
class SimpleVector {
    public:
        SimpleVector();
        SimpleVector(int);
        SimpleVector(const SimpleVector & copy);
        ~SimpleVector();
        int size();
        T getElementAt(int n);
        T & operator[](int index);

    private:
        T * item;
        int length;
};


int main() {


    int dType;
    int dataSize;

    cout << "What type of data do you want to enter?\n(1 for integer, 2 for double and 3 for strings)" << endl;
    cin >> dType;
    cout << "How many data inputs? " << endl;
    cin >> dataSize;

    SimpleVector <int> list1; // if I dont declare then for loop doesn't recognize list as a declared variable.
    if (dType == 0) {
        SimpleVector <int> list1(dataSize);
    }
    else if (dType == 1) {
        SimpleVector <double> list1(dataSize);
    }
    else {
        SimpleVector <string> list1(dataSize);
    }

    cout << "Please enter the data:" << endl;
    for (int i = 0; i < dataSize; i++) {
        cin >> list1[i];
    }



    return 0;
}

template <class T> SimpleVector<T>::SimpleVector() {
    item = NULL;
    length = 0;
}
template <class T> SimpleVector<T>::SimpleVector(int s) {
    length = s;
    item = new T[length];

}

template <class T> SimpleVector<T>::SimpleVector(const SimpleVector & copy) {
    int newSize = copy - > size();
    item = new T[newSize];

    for (int i = 0; i < newSize; i++)
    item[i] = copy.item[i];
}

template <class T> SimpleVector<T>::~SimpleVector() {
    delete[] item;
}

template <class T> int SimpleVector<T>::size() {
    return length;
}

template <class T> T SimpleVector<T>::getElementAt(int n) {
    return *(item + n);
}

template <class T> T & SimpleVector<T>::operator[](int index) {
    return this->item[index];
}

2 个答案:

答案 0 :(得分:1)

您无法切换数据类型。声明为特定类型的变量不能更改为其他类型。

变量具有范围。

{
    int a;
    .....stuff.....
}
// a cannot be accessed here.

a现在只能在开放{和关闭}之间使用。

{
    int a; // First a
    .....stuff..... // a refers to the first a here
        {
            int a;
            .....stuff..... // a refers to the second a here
        }
    .....stuff..... // a refers to the first a here
}

第二个a是与第一个不同的变量。它只能在它的范围内访问 - 即在离它最近的开括号和闭括号之间。

如果您真的想要动态类型,请尝试Boost.variantBoost.Any

答案 1 :(得分:1)

与Java一样,C ++是一种静态类型和静态范围的语言。这意味着必须在编译时知道变量的类型和生命周期。

  

在java中我一直认为在声明一个类之后你可以随时调用它的construtor,但是我不知道如何在C ++中这样做。

这与Java没有什么不同。在Java中,您尝试的将等同于:

MyClass c;
if (cond) {
   MyClass c = new MyClass(1);
} else  {
   MyClass c = new MyClass(2);
}

这与调用构造函数有 nothing 。它与您在嵌套作用域中声明新变量的事实有关,它们完全独立于外部作用域中同名的变量。

如果您需要运行时多态性,那么(根据定义),您实际上需要使用多态。也就是说,您需要使用虚函数创建公共基类:

class SimpleVectorBase
{
public:
    SimpleVectorBase() { }
    virtual ~SimpleVectorBase() { }

    virtual int size() const { return length; }

    // ... etc. ...

private:
    int length;
}

template <class T>
class SimpleVector : public SimpleVectorBase {
    // ...
}

int main() {
    // ...

    SimpleVectorBase* list1;
    if (dType == 0) {
        list1 = new SimpleVector<int>(dataSize);
    } else if (dType == 1) {
        list1 = new SimpleVector<double>(dataSize);
    } else {
        list1 = new SimpleVector<string>(dataSize);
    }

    // ...
}

但是,执行此操作并不能真正帮助您完成for循环。在你的特殊情况下,你可能最好不要对整个事情进行模板化:

template<typename T>
void doWork(int dataSize)
{
    SimpleVector<T> list1(dataSize);
    std::cout << "Please enter the data:" << std::endl;
    for (int i = 0; i < dataSize; i++) {
        std::cin >> list1[i];
    }
    // ... Do other stuff with list1 ...
}

然后你的main()函数会执行:

if (dType == 0) {
    doWork<int>(dataSize);
} else if (dType == 1) {
    doWork<double>(dataSize);
} else {
    doWork<string>(dataSize);
}