将类作为模板的类成员变量

时间:2013-07-04 23:41:44

标签: c++ templates

因此,在最近的C ++项目中,我实现了类似数据包工厂的系统,其中每个新数据包类都使用静态寄存器自动注册自身。其中一种数据包类型如下:

class Packet0Connect : public Packet{
public:
    Packet0Connect();
    Packet0Connect(const std::string& name, const std::string& info);
    virtual void write(std::ostream& os) const;
    virtual void read(std::istream& is);
    virtual Packet* clone() const;
    std::string name, info;
private:
    static const PacketRegister<Packet0Connect> registry;
};

这是PacketRegister的样子:

template<class P>
class PacketRegister{
public:
    PacketRegister(){
        PacketMap* packetMap = PacketManager::getPacketMap();
        if(packetMap->count(prototype.packetID) == 0){
            packetMap->insert(std::make_pair(prototype.packetID, (const Packet*)&prototype));
        }
    }
    P prototype;
};

注册表变量在实现文件的顶部正确初始化,并在其构造函数中添加映射到特定数据包类型,在本例中为Packet0Connect及其ID。我非常喜欢这种方式,因为它没有在堆栈上分配任何内存。以上编译使用Mac OSX上的GCC 4.2.1,但是,当我尝试在32位Windows Vista上使用Visual C ++ 2010进行编译时,我遇到了这个错误:

error C2079: 'PacketRegister<P>::prototype' uses undefined class 'Packet0Connect'
    with
    [
        P=Packet0Connect
    ]
    see reference to class template initialization 'PacketRegister<P>' being compiled
    with
    [
        P=Packet0Connect
    ]

在做了一些关于错误的谷歌搜索之后,我发现当你尝试使用前向声明的类作为模板参数时,它通常会被抛出。这确实有意义,因为当PacketRegister是,Packet0Connect没有完全定义,但必须有一种方法可以使用VC ++。我知道我可以在定义类之后使寄存器成为一个全局变量,但我不希望如果我能使它作为静态成员变量工作。

2 个答案:

答案 0 :(得分:0)

这是因为编译器无法确定Packet0Connect的大小。将Packet0Connect::registry的类型从PacketRegister<Packet0Connect>更改为PacketRegister<Packet0Connect> *

答案 1 :(得分:0)

也许PacketRegister和Packet0Connect中的每一个都依赖于另一个,并且您没有在PacketRegister之前声明Packet0Connect。仅限给定代码没问题。检查依赖项,您可能会向前声明它。