1

次のようなテンプレート化された抽象クラスをインスタンス化したいと思います。

template <class T>
class non_sense {
public:
    void virtual nonsesnse_func() = 0;
};

このクラスの整数インスタンスを作成するために、次のことを試しました。

void non_sense<int>::nonsesnse_func(){
}

次に、インスタンスを main に作成します。

non_sense<int> xx;

したがって、プログラム全体は次のようになります。

template <class T>
class non_sense {
public:
    void virtual nonsesnse_func() = 0;
};

void non_sense<int>::nonsesnse_func(){
}

void main(){
    non_sense<int> xx;
}

それは私には完全に理にかなっていますが、クラスが抽象的であると言って、コンパイラはそれを受け入れません。特定のテンプレートを使用してこのクラスから継承する新しいクラスを作成するルートを取りたくありません。これを作成しようとしている大きなアプリケーションに関しては、大量の書き込みになります。誰かがコンパイラがこれを拒否する理由を説明できますか?また、必要な特定のインスタンス用に新しいクラスを作成する以外に、これを回避する方法はありますか?

4

3 に答える 3

3

non_sense は抽象クラスであるため、インスタンス化してオブジェクトにすることはできません。

ただし、これはコンパイルして実行します。

#include <iostream>

template <class T>
class non_sense {
public:
    virtual void nonsesnse_func();
};

// Specialize the method
template<>
void non_sense<int>::nonsesnse_func(){
    std::cout << "no_sense<int>::nonsense_func" << std::endl;
}


int main(){
    non_sense<int> xx;

    xx.nonsesnse_func();

    return 0;
}

そして、これを純粋な抽象クラスで実行する方法を示すコードを次に示します (nosnsnsense を nonsense に名前を変更しました。入力しやすくなりました ;) :

#include <iostream>

template <class T>
class non_sense {
public:
    virtual void nonsense_func() = 0;
};

template<class T> 
class non_sense_concrete : public non_sense<T> {

    public: 
        void nonsense_func() {
            std::cout << "non_sense_concrete<T> generic code" << std::endl;
        }

};

// Specialize the concrete class
template<>
void non_sense_concrete<int>::nonsense_func(){
    std::cout << "no_sense<int>::nonsense_func" << std::endl;
}


int main(){

    non_sense_concrete<double> objectGeneric;
    objectGeneric.nonsense_func(); 

    non_sense_concrete<int> objectInt;
    objectInt.nonsense_func();


    return 0;
}
于 2013-01-08T11:27:44.477 に答える
1

奇妙に思えるかもしれませんが、純粋仮想メソッドは C++ で実装できます。それは、メソッドが純粋な仮想であり、それを含むクラスが抽象であるという事実を変更しません。

クラスnon_senseを を除くすべての型に対して抽象化するint場合は、純粋な仮想メンバーだけでなく、クラス全体に特殊化を提供する必要があります。

template <class T>
class non_sense {
public:
    virtual void nonsense_func() = 0;
};

template <>
class non_sense<int> {
public:
    virtual void nonsense_func()
    {
        std::cout << "no_sense<int>::nonsense_func" << std::endl;
    }
};

より大きなクラスを使用すると、派生クラスが から他のメンバーを継承できるため、non_senseクラス全体を複製する必要がなくなります (特殊化を作成するときに行う必要があります)。

于 2013-01-08T11:45:45.510 に答える
0

純粋な仮想関数 (つまり抽象) を持つクラスがある場合は、その仮想関数を実装する 2 番目のクラスを作成する必要があります。そうしないと、そのクラスを使用できなくなります。

あなたのコードでは、関数を問題なく実装しましたが、クラス内にないため、仮想ではありません。動作させるには、non_sense のサブクラスの一部として宣言および定義する必要があります。仮想関数を持つことができるのはクラスだけであることに注意してください。

于 2013-01-08T11:42:11.210 に答える