繁体   English   中英

以类为模板的类成员变量

[英]Class member variable that takes the class as a template

因此,在最近的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;
};

注册表变量已在实现文件的顶部正确初始化,并在其构造函数中使用其ID向特定的数据包类型(在本例中为Packet0Connect)添加了映射。 我很喜欢这样做,因为它不会在堆栈上分配任何内存。 上面的代码在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 ++一起使用。 我知道我可以在定义类后使寄存器成为全局变量,但是我不希望它可以作为静态成员变量工作。

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

PacketRegister和Packet0Connect可能彼此依赖,并且您没有在PacketRegister之前声明Packet0Connect。 仅使用给定代码没有问题。 检查依赖关系,您可能会向前声明它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM