在使用模板类作为父类时一个关于静态变量的问题

在使用模板类的静态变量时遇到了一个问题,现在总结如下。

对于钢筋、型钢、混凝土等类似的有限个类型的数据结构,可以统一采用Factory Method设计模式,通过Create(结构类型)静态函数构造。

为此,设计一个模板基类如下:

 

FiniteClassBase.h

    template<typename TClass, typename TType>

    class  FiniteClassBase

    {

    public:

        virtual ~FiniteClassBase() {};

 

        static std::shared_ptr<TClass> Create(TType type)

        {

            if (stockVal[type])

            {

                return stockVal[type];

            }

            else

            {

                stockVal[type] = std::shared_ptr<TClass>(new TClass(type));

                return stockVal[type];

            }

        };

    protected:

        FiniteClassBase() {};

 

        static std::map<TType, std::shared_ptr<TClass>> stockVal;

    };

 

对于一个钢筋类,可以派生自FiniteClassBase

MateBar.h

    class  MateBar

        : public FiniteClassBase<MateBar, BarType>

    {

        friend class FiniteClassBase<MateBar, BarType>;

    public:

        ~MateBar();    

        double GetFy()const { return fy; };

    private:

        MateBar(BarType type);

 

        double fy;

    };

其中BarType为枚举类型,  enum class BarType { HPB300, HRB335, HRB400, HRB500 };

很简单的一个思路,但是在使用时要注意一下问题。

1、声明有元类,friend class FiniteClassBase<MateBar, BarType>,这样基类才能访问其构造函数。

2、MateBarcpp文件中要做如下声明:

//! 显式实例化,否则调用Create时会提示找不到符号

template class cy::FiniteClassBase<cy::MateBar, cy::BarType>;

 

//! 模板静态变量的初始化,否则会提示找不到符号

std::map<BarType, std::shared_ptr<MateBar>> FiniteClassBase<MateBar, BarType>::stockVal;

至于原因,摘自百度 模板函数在声明的时候, 其实并不存在,函数地址也就无从谈起了,而导出到动态链接库的函数都需要有地址,也就是说——函数模板不具备导出的基本条件。  

函数模板在调用时后,有了具体的实现,这个时候才有了地址。   如果要导出,必须将参数类型列表具体化。也就是要显式实例化。

至于静态变量的初始化,应该在每个子类的cpp文件中初始化一次。因为模板静态变量在每个子类中是不同的,所以子类要初始化。

 

转载于:https://www.cnblogs.com/ljy339/p/7507078.html


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部