具有纯虚拟函数的模板类的C++语法

C++ syntax of template class with pure virtual function?

本文关键字:C++ 语法 虚拟 函数      更新时间:2023-10-16

我对C++模板的熟悉程度很低,在模板类中添加纯虚拟函数已经耗尽了我满足编译器的能力。

以下代码。。。

#include <iostream>
#include <string>
#include <sstream>
class Pearl
{
    public:
        Pearl(int value);
        virtual ~Pearl();
    protected:
        int mValue;
};
Pearl::Pearl(int value)
    : mValue(value)
{
    std::cout << "$" << mValue << " Pearl created" << std::endl;
}
Pearl::~Pearl()
{
    std::cout << "$" << mValue << " Pearl destroyed" << std::endl;
}
///////////////////////////////////////////////////////////////////////
class Oyster
{
    public:
        Oyster(std::string str, int value);
        virtual ~Oyster();
    protected:
        Pearl mPearl;
        std::string mName;
    friend class OStreamer;
};
Oyster::Oyster(std::string name, int value)
    : mName(name)
    , mPearl(value)
{
    std::cout << "Oyster " << mName << " created" << std::endl;
}
Oyster::~Oyster()
{
    std::cout << "Oyster " << mName << " destroyed" << std::endl;
}
///////////////////////////////////////////////////////////////////////
template <typename T> class Streamer
{
    public:
        Streamer(T& rT, unsigned int flags);
        ~Streamer();
        virtual std::ostream Display() = 0;
        static const unsigned int A = 0x1;
        static const unsigned int B = 0x2;
    protected:
        T& mrT; // Aah pity the foo!
        unsigned int mFlags;
    friend class OStreamer;
};
///////////////////////////////////////////////////////////////////////
class OStreamer : public Streamer<Oyster>
{
    public:
        OStreamer(Oyster oyster, unsigned int flags);
        virtual std::ostream Display();
};
OStreamer::OStreamer(Oyster oyster, unsigned int flags)
    : Streamer<Oyster>(oyster, flags)
{
}
std::ostream OStreamer::Display()
{
    std::ostringstream oss;
    oss << "Oyster[" << mrT.mName << "]" << std::endl;
}
///////////////////////////////////////////////////////////////////////
template <typename T> std::ostream& operator<<(std::ostream& os, const Streamer<T> streamer)
{
    return os;
}
///////////////////////////////////////////////////////////////////////
int main()
{
    Oyster sam("Sam", 50);
    std::cout << OStreamer(sam, OStreamer::A) << std::endl;
    return 0;
}

生成以下编译器错误(g++4.4.7):

>g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:107: error: cannot allocate an object of abstract type ‘Streamer<Oyster>’
main.cpp:56: note:   because the following virtual functions are pure within ‘Streamer<Oyster>’:
main.cpp:61: note:      std::ostream Streamer<T>::Display() [with T = Oyster]

有人能帮我理解为什么编译器不接受OStreamer::Display()的实现作为Streamer::Display(()的必需覆盖吗?

作为上下文:这是一个实验性的、人为的代码,以熟悉将模板类与纯虚拟函数相结合。我想用这段代码实现的是为调用OStreamer::Display的OStreamer对象实现一个otream运算符。我知道ostream操作符可能需要一些调整,但我认为这不是问题所在。

将操作员过载更改为:

template <typename T> std::ostream& operator<<(std::ostream& os,
                           const Streamer<T> &streamer)
{
    return os;
}

传递参数const Streamer<t>需要复制基类,当然这是不可能的,因为它是虚拟的。

传递引用可以避免此问题。