2014-04-03 19 views
0

我正在做一个内存池的一个项目工作,但我有问题的清单编译它:C++链接不同的子类

我有一个内存池类(在下面R中的例子),其中有一个模板参数来保存实际使用的类。每个类是Descriptor的一个子类。

我认为我可以创建一个R对象的链表,但是当我尝试追加一个包含子类描述符的R类时,编译器抱怨类型转换。

有关如何解决此编译错误的任何建议?

g++-4.7 -g -ggdb -DDEBUG=1 -Wall -std=c++11 -march=native -m64 -DINTEL -fno-strict-aliasing example.cpp -o example.x 
example.cpp: In instantiation of ‘void n1::n2::R<D>::add() [with D = n1::n2::SubDescriptor2<int, int>]’: 
example.cpp:68:14: required from here 
example.cpp:37:10: error: cannot convert ‘n1::n2::R<n1::n2::SubDescriptor2<int, int> >* const’ to ‘n1::n2::R<n1::n2::Descriptor>*’ in assignment 
example.cpp: In instantiation of ‘void n1::n2::R<D>::add() [with D = n1::n3::SubDescriptor<int, int>]’: 
example.cpp:72:13: required from here 
example.cpp:37:10: error: cannot convert ‘n1::n2::R<n1::n3::SubDescriptor<int, int> >* const’ to ‘n1::n2::R<n1::n2::Descriptor>*’ in assignment 

工作示例:

#include <cstdint> 
#include <utility> 
#include <stdlib.h> 
namespace n1 { 
    namespace n2 { 
    class Descriptor; 
    template<class D> 
    class R; 


    class Descriptor { 
     public: 
      int temp; 

      Descriptor() {} 
      Descriptor(int x) { 
      temp = x; 
      } 
      ~Descriptor() {} 
    }; 

    R<Descriptor> * list = nullptr; 

    template<class D> 
    class R { 
    public: 
     R<Descriptor> *pool_next; 
     D descriptor; //EDIT for some reason I only had d here... 

     template<typename... Args> 
     R(Args&&... args): descriptor(std::forward<Args>(args)...) { 
     }; 


     void add() { 
     this->pool_next = list; 
     list = this; 
     } 
    }; 

    template<class T, class W> 
     class SubDescriptor2: public Descriptor { 
     public: 
     SubDescriptor2(int x) { 
      temp = x; 
     }; 
     ~SubDescriptor2() {}; 
     }; 
    }; 


    namespace n3{ 
    template<class T, class W> 
    class SubDescriptor: public n2::Descriptor { 
    public: 
     SubDescriptor(int x) { 
      temp = x; 
     }; 
     ~SubDescriptor() {}; 
    }; 
    }; 
}; 

int main(int argc, const char * argv[]) { 

    n1::n2::R< n1::n2::SubDescriptor2<int, int> > *temp2; 
    temp2 = new n1::n2::R< n1::n2::SubDescriptor2<int, int> >(1); 
    temp2->add(); 

    n1::n2::R< n1::n3::SubDescriptor<int, int> > *temp; 
    temp = new n1::n2::R< n1::n3::SubDescriptor<int, int> >(1); 
    temp->add(); 
    return 1; 
} 
+0

我的第一件事使用相同的命令调用可以看到至少2个其他编译错误。我很确定你必须先解决这些问题。 –

+0

我没有收到任何其他错误,你可以发布你的错误? –

+0

你确定这是你正在编译的确切代码吗?这里有两个: const.cc:31:26:错误:成员初始化'descriptor'没有命名非静态数据成员或基类 R(Args && ... args):描述符(std :: forward (args)...){ ^ ~~~~~~~~~~~~~~~~~~~~~~ const .cc:37:15:错误:从不兼容类型'n1 :: n2 :: R >'''''分配给'R *''''' list =这个; –

回答

1

R<SubDescriptor>不是R<Descriptor>一个子类。这是因为C++模板不是covariant

我能想到的一个解决办法是保持在R类Descriptor*,实例化所有R与描述符作为他们的模板参数,并costructing当通过描述的不同的子类新R.

+0

有道理,但它不适用于我的用例,我希望R和描述符共同位于内存池中,以避免额外的指针间接级别....感谢您的链接和解释。 在我的应用程序中,我要求所有描述符对象的大小小于缓存行,并且每个R分配都被强制为缓存行大小。是否会对虚拟功能的调用产生负面影响? –

+0

我不能肯定地回答铸造问题,但我不会这样做。如何这样的事情:class RBase {virtual Descriptor * getDescriptor()= 0; }然后模板 class R:RBase?这将添加另一个虚拟指针来满足内存要求。 –