gpt4 book ai didi

c++ - 返回模板子类

转载 作者:行者123 更新时间:2023-11-28 03:49:49 25 4
gpt4 key购买 nike

我有一堆容器和对象。容器和对象具有模板化的子类。那些模板化的子类有专门的子类。在专门的对象中,我想检索它们的容器。这是代码设置:

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。

我的问题是:如何检索正确的 SubContainerGetSubContainer()SubObject

我希望这是有道理的。

最佳答案

对代码的最小更改是:

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;
}

对象或容器的公共(public)功能分别实现为对象或容器的成员函数。

对象或容器的按类型功能是通过策略对象的组合实现的,您可以使用工厂根据适当的策略生成适当的对象和容器。

我提出了一种相当灵活的方法(可能过于灵活),因此您可以忽略模板特化或策略对象上的继承,具体取决于您对行为的具体需求。

关于c++ - 返回模板子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5891212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com