简体   繁体   English

C ++将派生类作为基类模板参数传递

[英]C++ Passing a derived class as a base class template parameter

I'm having trouble passing a class DerivedObject (part of class DerivedClass derived from template class BaseClass ) derived from BaseObject (part of template class BaseClass ) as a template argument to template class BaseClass . 我在传递一个类的麻烦DerivedObject (类的一部分DerivedClass从模板类派生BaseClass源自) BaseObject (模板类的一部分BaseClass )作为模板参数模板类BaseClass

This way, both Base and Derived classes have the access to the object pool, that can contain derived objects. 这样,Base和Derived类都可以访问对象池,该对象池可以包含派生对象。 This sounds a bit confusing, so here is the example: 这听起来有点令人困惑,所以这是一个例子:

template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
protected:
    class BaseObject
    {
        // Class implementation
    }
    void foo() 
    { 
        static_cast<TDerivedClass*>(this)->foo(); 
    }
    std::vector<TDerivedObject*> m_objectPool;
};

The above is the base class implementation. 以上是基类实现。

error C2065: 'DerivedObject' undeclared identifier

The above error is cause by the first line of the class definition bellow: 上面的错误是由类定义的第一行引起的:

class DerivedClass : public BaseClass<DerivedClass, DerivedClass::DerivedObject>
{
protected:
    class DerivedObject : public BaseObject
    {
        // Class implementation
    }
    void foo()
    {
        // Method implementation
    }
};

Is there a way to do this? 有没有办法做到这一点? If not, is there a better solution that would give me the same / similar functionality? 如果没有,是否有更好的解决方案可以提供相同/类似的功能?

At this point 这一点

class DerivedClass : public BaseClass<DerivedClass, DerivedClass::DerivedObject>

The compiler has not seen DerivedClass::DerivedObject so you get an undeclared identifier error. 编译器没有看到DerivedClass::DerivedObject因此您得到未声明的标识符错误。 As they type has not been seen you cannot use it as a template parameter. 由于尚未看到它们的类型,因此无法将其用作模板参数。 You don't get one for DerivedClass as you already have declared DerivedClass as a class . 您没有为DerivedClass获取一个,因为您已经将DerivedClass声明为class

You could change you base class and have it store a std::vector<BaseObject*> in it and if you do that then you can change your code to: 您可以更改基类并让它在其中存储std::vector<BaseObject*> ,如果您这样做,那么您可以将代码更改为:

template <class TDerivedClass>
class BaseClass
{
protected:
    class BaseObject
    {
        // Class implementation
    };
    void foo() 
    { 
        static_cast<TDerivedClass*>(this)->foo(); 
    }
    std::vector<BaseObject*> m_objectPool;
};

class DerivedClass : public BaseClass<DerivedClass>
{
protected:
    class DerivedObject : public BaseObject
    {
        // Class implementation
    };
    void foo()
    {
        // Method implementation
    }
};

From your example code, I get the impression that you want to provide different implementations for different base classes. 从您的示例代码中,我得到的印象是您希望为不同的基类提供不同的实现。 Is there any special reason for using templates? 使用模板有什么特殊原因吗? If not, you could use classic polymorphism instead: 如果没有,您可以使用经典多态性:

class BaseClass
{
  class BaseObject {};
  virtual ~BaseClass() {} // <- do not forget to provide virtual dtor!
  virtual void foo() = 0;
  std::vector<BaseObject*> m_objectPool;
};
class DerivedClass : public BaseClass
{
  class DerivedObject : public BaseObject {/*...*/};
  virtual void foo(){/*...*/}
};

Again, BaseObject would offer virtual or pure virtual functions - as you need. 同样,BaseObject将提供虚拟或纯虚函数 - 根据需要。

One thing, however, you lose this way: the guarantee that in the vector there are always the objects of one specific BaseObject sub-type. 但是,有一件事你会失去这种方式:保证在向量中始终存在一个特定BaseObject子类型的对象。 If this matters for you, you could protect the pool and only allow to add new BaseObjects via DerivedClass. 如果这对您很重要,则可以保护池,并且只允许通过DerivedClass添加新的BaseObject。 If this is not applicable, I might think up another solution from within BaseClass. 如果这不适用,我可能会想到BaseClass中的另一个解决方案。

Here is one way of doing something similar to what was requested: 这是做出类似于所要求的事情的一种方式:

#include <vector>

using std::vector;

template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
public:
    class BaseObject
    {
        // Class implementation                                                                                                                                                                                                              
    };

protected:
    // void foo()                                                                                                                                                                                                                            
    // {                                                                                                                                                                                                                                     
    //     static_cast<TDerivedClass*>(this)->foo();                                                                                                                                                                                         
    // }                                                                                                                                                                                                                                     
    // std::vector<TDerivedObject*> m_objectPool;                                                                                                                                                                                            
};

class DerivedClass;
class DerivedObject : public BaseClass<DerivedClass, DerivedObject>::BaseObject
{
    // Class implementation                                                                                                                                                                                                                  
};

class DerivedClass : public BaseClass<DerivedClass, DerivedObject>
{
public:
    void foo()
    {
        // Method implementation                                                                                                                                                                                                             
    }
};

If you do not mind having the DerivedObject structure separately from the DerivedClass you may do something like that: 如果您不介意将DerivedObject结构与DerivedClass分开,您可以执行以下操作:

template <class T>                                                                                                                                           
struct ObjectTypeTrait                                                                                                                                       
{                                                                                                                                                            
   static_assert(sizeof(T) == 0, "undefined trait");                                                                                                                      
};

template <class TDerivedClass>                                                                                                                               
class BaseClass                                                                                                                                              
{                                                                                                                                                            
protected:                                                                                                                                                   
class BaseObject                                                                                                                                         
{                                                                                                                                                        
  // Class implementation                                                                                                                                
};                                                                                                                                                       

void foo()                                                                                                                                             
{                                                                                                                                                          
   static_cast<TDerivedClass*>(this)->foo();                                                                                                                
}                                                                                                                                                          
std::vector<typename ObjectTypeTrait<TDerivedClass>::obj*> m_objectPool;                                                                                   
};

class DerivedClass;                                                                                                                                          

class DerivedObject                                                                                                                                        
{                                                                                                                                                          
   // Class implementation                                                                                                                                  
};                                                                                                                                                         


template<>                                                                                                                                                   
struct  ObjectTypeTrait<DerivedClass>                                                                                                                        
{                                                                                                                                                           
   using obj = DerivedObject;                                                                                                                                
};                                                                                                                                                          


class DerivedClass : public BaseClass<DerivedClass>                                                                                                          
{                                                                                                                                                            
protected:                                                                                                                                                   


    void foo()                                                                                                                                                 
    {                                                                                                                                                          
      // Method implementation                                                                                                                                 
    }                                                                                                                                                          
 };

I do not claim this to be very brilliant solution, but you can get the idea - using type traits or typedefs 我并不认为这是一个非常出色的解决方案,但你可以得到这个想法 - 使用类型特征或typedef

暂无
暂无

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

相关问题 为什么在调用基类复制构造函数(C ++)时将派生类类型作为参数传递? - Why passing derived class type as parameter when calling base class copy constructor (C++)? 将数组指针从派生类传递到基类C ++ - Passing array pointer from derived class to base class C++ C ++基类是否可能具有带有派生类的参数的函数 - C++ Is it possible that the base class has a function with a parameter of the derived class C ++ - 智能指针 - 通过模板将派生类共享指针传递给base - C++ - Smart Pointers - Passing derived class shared pointer to base through template C++:为模板参数指定基础 class - C++: specifying a base class for a template parameter 将派生类的成员函数指针作为参数传递时,选择了错误的C ++模板专业化 - C++ Wrong template specialization selected when passing member function pointer of derived class as a parameter C++ 派生模板 class 继承自模板基础 class,无法调用基础 ZA2F2ED4F8EBC2CBB4C21A29DC40AB6 构造函数 - C++ derived template class is inheriting from template base class, cannot call base class constructor 在C ++中将模板类引用作为参数传递 - Passing in template class reference as parameter in c++ 可以将派生对象转换为c ++模板类中的基本引用吗? - Can derived object cast to base reference in c++ template class? 带有 std::is_base_of 的派生类的 C++ 模板函数 - C++ template function for derived class with std::is_base_of
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM