返回模板子类
returning template subclass
我有一堆容器和对象。 容器和对象具有模板化子类。 这些模板化子类具有专用子类。 在专用对象中,我想检索它们的容器。 下面是代码设置:
class Container;
template<class T> class SubContainer;
class Object
{
public:
Object() : m_pContainer(NULL) { }
public:
Container* GetContainer()
{
return m_pContainer;
}
void SetContainer(Container* pContainer)
{
m_pContainer = pContainer;
}
private:
Container* m_pContainer;
};
class Container
{
public:
Container() : m_pObject(NULL) { }
virtual ~Container() { }
public:
void SetObject(Object* pObject)
{
m_pObject = pObject;
m_pObject->SetContainer(this);
}
protected:
Object* m_pObject;
};
template<class T>
class SubObject : public Object
{
public:
virtual SubContainer<SubObject>* GetSubContainer()
{
return dynamic_cast<SubContainer<SubObject>*>(GetContainer());
}
void TestMe()
{
SubContainer<SubObject>* pSubContainer = GetSubContainer();
assert(pSubContainer);
}
};
template<class T>
class SubContainer : public Container
{
};
class SubObjectInt : public SubObject<int>
{
};
class SubContainerSubObjectInt : public SubContainer<SubObject<int> > // works
//class SubContainerSubObjectInt : public SubContainer<SubObjectInt> // fails
{
};
测试代码:
SubContainerSubObjectInt* pContainer = new SubContainerSubObjectInt();
SubObjectInt* pObject = new SubObjectInt();
pContainer->SetObject(pObject);
pObject->TestMe();
我知道SubContainer<SubObjectInt>
不是SubContainer<SubObject<int> >
的子类,即使SubObjectInt
是SubObject<int>
的子类。
我将代码标记为"工作"和"失败"。 "失败"的行在我的代码中更合乎逻辑,但我无法检索保存它的正确子容器。 动态强制转换始终返回 NULL。
我的问题是:如何在SubObject
中检索正确的GetSubContainer()
SubContainer
?
我希望这是有道理的。
对代码的最小更改是更改:
class SubObjectInt : public SubObject<int>
{
};
自
typedef SubObject<int> SubObjectInt;
当前失败的定义现在将编译并返回有效的指针。
如果您希望特定代码特定于不同于 SubObject 的 SubObjectInt,则可以改为:
template<class T>
class SubObject : public Object
{
public:
typedef SubContainer<SubObject<T> > ContainerType;
ContainerType* GetSubContainer()
{
Container* container = GetContainer();
return dynamic_cast<ContainerType*>(container);
}
void TestMe()
{
ContainerType* pSubContainer = GetSubContainer();
assert(pSubContainer);
}
};
然后你的测试代码看起来像这样:
SubObjectInt::ContainerType* pContainer = new SubObjectInt::ContainerType();
SubObjectInt* pObject = new SubObjectInt();
pContainer->SetObject(pObject);
pObject->TestMe();
编辑:回应第一条评论
好吧,我想说你可能最好使用不同的设计,你正在混合继承、组合和模板,使我认为你想要实现的目标复杂化。
您有一个希望能够分配对象的容器类型。您有一个想要了解其容器的对象类型。
您希望容器和对象类型根据其内容执行相同的操作和不同的操作。
我会提出这样的建议:
template<class T>
class ObjectStrategy
{
public:
virtual void execute(T* object)
{
std::cout << "oh noes i am a default general ObjectStrategy" << std::endl;
}
};
template<class T>
class ContainerStrategy
{
public:
virtual void execute(T* container)
{
std::cout << "oops i am a default general ContainerStrategy" << std::endl;
}
};
template<class T>
class Object;
template<class T>
class Container
{
public:
Container() : m_pObject(0), m_strategy(new ContainerStrategy<Container<T> >()) { }
Container(ContainerStrategy<Container<T> >* strategy_override) : m_pObject(0), m_strategy(strategy_override) { }
~Container() { delete m_strategy; }
void SetObject(T* pObject)
{
m_pObject = pObject;
m_pObject->SetContainer(this);
}
void DoContainerStuff()
{
m_strategy->execute(this);
}
protected:
T* m_pObject;
ContainerStrategy<Container<T> >* m_strategy;
};
template<class T>
class Object
{
public:
Object() : m_pContainer(0), m_strategy(new ObjectStrategy<Object<T> >()) { }
Object(ObjectStrategy<Object<T> >* strategy_override) : m_pContainer(0), m_strategy(strategy_override) { }
~Object() { delete m_strategy; }
Container<Object<T> >* GetContainer()
{
return m_pContainer;
}
void SetContainer(Container<Object<T> >* pContainer)
{
m_pContainer = pContainer;
}
void DoObjectStuff()
{
m_strategy->execute(this);
}
void TestMe()
{
DoObjectStuff();
Container<Object<T> >* pContainer = GetContainer();
pContainer->DoContainerStuff();
}
protected:
Container<Object<T> >* m_pContainer;
ObjectStrategy<Object<T> >* m_strategy;
};
typedef Object<int> ObjectInt;
template<>
class ObjectStrategy<ObjectInt>
{
public:
virtual void execute(ObjectInt* container)
{
std::cout << "omg i am a default specific strategy for ObjectInt" << std::endl;
}
};
typedef Container<ObjectInt> ContainerObjectInt;
template<>
class ContainerStrategy<ContainerObjectInt>
{
public:
virtual void execute(ContainerObjectInt* container)
{
std::cout << "pow i am a default specific strategy for ContainerObjectInt" << std::endl;
}
};
class ObjectIntOverrideStrategy : public ObjectStrategy<ObjectInt>
{
public:
virtual void execute(ObjectInt* object)
{
std::cout << "bam i am an overriding specific strategy for ObjectInt" << std::endl;
}
};
class ContainerObjectIntOverrideStrategy : public ContainerStrategy<ContainerObjectInt>
{
public:
virtual void execute(ContainerObjectInt* object)
{
std::cout << "woo i am an overriding specific strategy ContainerObjectInt" << std::endl;
}
};
int main(int argc, char** argv)
{
{ // test with default + general strategies
typedef Object<float> ObjectFloat;
typedef Container<ObjectFloat> ContainerObjectFloat;
ObjectFloat* pObject = new ObjectFloat();
ContainerObjectFloat* pContainer = new ContainerObjectFloat();
pContainer->SetObject(pObject);
pObject->TestMe();
}
{ // test with default + specific strategies
ObjectInt* pObject = new ObjectInt;
ContainerObjectInt* pContainer = new ContainerObjectInt;
pContainer->SetObject(pObject);
pObject->TestMe();
}
{ // test with overriding + specific strategies
ObjectInt* pObject = new ObjectInt(new ObjectIntOverrideStrategy);
ContainerObjectInt* pContainer = new ContainerObjectInt(new ContainerObjectIntOverrideStrategy);
pContainer->SetObject(pObject);
pObject->TestMe();
}
return 0;
}
对象或容器的通用功能分别作为对象或容器的成员函数实现。
对象或容器的每种类型的功能是通过策略对象的组合来实现的,您可以使用工厂根据适当的策略生成适当的对象和容器。
我提出了一个相当灵活的方法(可能太灵活了),所以你可以忽略策略对象的模板专用化或继承,这取决于你需要行为的具体程度。
你可以尝试这样的事情:
class SubObjectInt : public SubObject<int>
{
public:
typedef SubObject<int> parent;
};
class SubContainerSubObjectInt
: virtual public SubContainer<SubObjectInt>
, virtual public SubContainer<SubObjectInt::parent>
{
public:
void SetObject(Object* pObject)
{
SubContainer<SubObjectInt::parent>::SetObject(pObject);
}
};
为了更简洁,您应该私下从子容器继承,并将所需的实际方法重新发布为公共成员。
- 从父类方法返回子类对象
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 返回具体子类实例的 C++ 虚拟类函数
- 我如何使子类返回C 中的不那么通用的Typedef
- 当函数返回类型为父类时,如何返回子类的对象?
- 如何使函数返回由子类定义的值?C++
- 提升 Python 包装的虚拟类 - 子类返回错误:与C++签名不匹配
- 将子类返回到基类对象中
- 用返回子类的方法设计C++泛型类
- 为什么编译没有错误?(返回不对所述返回类型进行子类化的类型)
- 返回子类的常量引用
- C++:使用超类和子类,简单计算面积的值返回3.47668e-310,无论我输入什么来计算
- 返回指向子类的指针的好方法
- C++方法返回指向抽象类的指针,需要使用来自子类的方法
- 从超类函数返回子类定义
- 重写QIODevice子类中的readData会返回错误的结果
- 重写子类中的返回类型
- 如何返回“set”方法的子类类型
- 方法返回子类的实例
- 可以对返回子类类型的基类进行赋值操作符吗?