1

そのため、単純なベクトル テンプレートを作成するように依頼されました。教科書 (Savitch) の一般化されたリストの例をいくつか見て、クラスを正しく作成したと思います。今main()、ユーザーにデータ型を選択させることで、クラスを呼び出そうとしています。identifier を宣言した後、問題が発生していますlist1。if文でデータ型を切り替えた後、同じ識別子を使えるようにしたい。list1ただし、既に宣言されているため、if ステートメントの本文の構文は正しいとは思いません。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 ++は、Javaと同様に、静的に型付けされ、静的にスコープされた言語です。これは、変数のタイプと存続期間をコンパイル時に知る必要があることを意味します。

Javaでは、クラスが宣言された後、いつでもそのコンストラクターを呼び出すことができるといつも思っていましたが、C++でそれを行う方法がわかりません。

これはJavaと同じです。Javaでは、試行していることは次のことと同じです。

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

これは、コンストラクターの呼び出しとは何の関係もありません。これは、ネストされたスコープで新しい変数を宣言しているという事実と関係があり、それらは外部スコープで同じ名前の変数から完全に独立しています。

実行時のポリモーフィズムが必要な場合は、(定義上)実際にはポリモーフィズムを使用する必要があります。つまり、仮想関数を使用して共通の基本クラスを作成する必要があります。

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

2 番目aは、最初の変数とは異なる変数です。スコープのみにアクセスできます。つまり、それに最も近い開き括弧と閉じ括弧の間です。

本当に動的な型が必要な場合は、Boost.variantまたはを試してくださいBoost.Any

于 2012-12-03T03:23:33.957 に答える