1

所以我被要求写一个简单的向量模板,我相信我已经正确地写了这门课,看看我们教科书 (Savitch) 中的一些广义列表的例子。现在我试图main()通过让用户选择数据类型来调用类。声明标识符后,我遇到了问题list1。在使用 if 语句切换数据类型后,我希望能够使用相同的标识符。但是,我不认为我的 if 语句主体中的语法是正确的,因为list1已经声明了。在java中,我一直认为在声明一个类之后你可以随时调用它的构造函数,但我不知道如何在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];
}
4

2 回答 2

1

C++, like Java, is a statically typed and statically scoped language. This means that the type and lifetime of variables must be known at compilation time.

In java I always thought after a class is declared you can call its construtor at any time, but I have no idea how to do that in C++.

This is not different from Java. In Java, what you're attempting would be equivalent to doing:

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

This has nothing to do with calling constructors. It has to do with the fact that you're declaring new variables in nested scopes, and they are completely independent of variables of the same name in outer scopes.

If you need runtime polymorphism, then (by definition), you actually need to use polymorphism. That is, you need to create a common base class with virtual functions:

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);
    }

    // ...
}

However, doing this won't really help you with your for loop. In your particular case, you probably would be better off templatizing the whole thing:

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 ...
}

and then your main() function would do:

if (dType == 0) {
    doWork<int>(dataSize);
} else if (dType == 1) {
    doWork<double>(dataSize);
} else {
    doWork<string>(dataSize);
}
于 2012-12-03T03:39:46.857 回答
1

您不能切换数据类型。一旦声明为特定类型的变量不能更改为不同的类型。

变量有范围。

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

a现在只能在 open{和 close之间使用}

{
    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.variantor Boost.Any

于 2012-12-03T03:23:33.957 回答