gpt4 book ai didi

接口(interface) ptr 的 C++ 返回 vector

转载 作者:太空狗 更新时间:2023-10-29 20:35:23 25 4
gpt4 key购买 nike

我正在尝试创建一个返回接口(interface) vector 的接口(interface),同时使用它在另一端实现。

我知道这不是很清楚,所以这里有例子:

class IComponent
{
public:
virtual ~IComponent() {}

virtual int getValue() const = 0;
};

class ICollection
{
public:
virtual ~ICollection() {}

virtual IComponent* getComp() = 0;
};

class Component : public IComponent
{
public:
virtual int getValue() const { return 42; }
};

class Collection : public ICollection
{
public:
Collection()
{
m_comp = new Component();
}
virtual Component* getComp()
{
return m_comp;
}

private:
Component* m_comp;
};

这个编译和工作,因为Component*隐式转换为 IComponent* .这让我可以使用一个完全实现的 CollectionComponent .

#include <vector>

class IComponent
{
public:
virtual ~IComponent() {}

virtual int getValue() const = 0;
};

class ICollection
{
public:
virtual ~ICollection() {}

virtual std::vector<IComponent*> &getComp() = 0;
};

class Component : public IComponent
{
public:
virtual int getValue() const { return 42; }
};

class Collection : public ICollection
{
public:
Collection()
{
m_comp.push_back(new Component());
m_comp.push_back(new Component());
}
virtual std::vector<Component*> &getComp()
{
return m_comp;
}

private:
std::vector<Component*> m_comp;
};

但这次我无法使用完全实现的 Collection 和 Component。

当然很容易理解为什么,因为Component *IComponent * ,但严格来说,std::vector<Component *>不是 std::vector<IComponent *> .这个问题也适用于所有模板类型,如迭代器、smart_ptr 等...

相反,在 Collection::getComp()我必须返回 std::vector<IComponent *> .我也许可以投 m_comp在归还它时(我什至不确定它是否有效,它不是右值吗?)。我还可以存储 2 vector , Component * 之一和 IComponent * 之一,并使它们保持同步,但我认为这是丑陋的代码。

是否有一些解决方法,或者我不知道的某种方式来处理它?<​​/p>

更多详情:

我真正想要的是能够使用 ComponentCollection .如果我改变 m_compstd::vector<IComponent *>getComp()返回类型它会起作用,但我将被迫使用指向 IComponent 的指针而不是 ComponentCollection .

是的,我可以同步两个 vector ,或者在 getComp() 中创建一个拷贝, 但我想知道是否有更好的方法。

事件更多详情:

这是我想如何使用它的一个例子:(我只是在 getDouble() 中添加了 Component 方法,并在 Collection 中调用了它)

#include <iostream>
#include <vector>

class IComponent
{
public:
virtual ~IComponent() {}

virtual int getValue() const = 0;
};

class ICollection
{
public:
virtual ~ICollection() {}

virtual std::vector<IComponent*> &getComp() = 0;
};

class Component : public IComponent
{
public:
virtual int getValue() const { return 42; }
double getDouble() const { return 3.14; }
};

class Collection : public ICollection
{
public:
Collection()
{
m_comp.push_back(new Component());
m_comp.push_back(new Component());
}
// Impossible because it does not override the good method
virtual std::vector<Component*> &getComp()
{
std::cout << m_comp[0]->getDouble() << std::endl;
return m_comp;
}

private:
std::vector<Component*> m_comp;
};

如果我更改返回类型,Collection 将变为:

class Collection : public ICollection
{
public:
Collection()
{
m_comp.push_back(new Component());
m_comp.push_back(new Component());
}
virtual std::vector<IComponent*> &getComp()
{
// This time this line is impossible without cast
// because m_comp[0] is IComponent*
std::cout << m_comp[0]->getDouble() << std::endl;
return m_comp;
}

private:
std::vector<IComponent*> m_comp;
};

一个解决方案是这样的:

class Collection : public ICollection
{
public:
Collection()
{
// Useless and redundant code here
m_comp.push_back(new Component());
m_icomp.push_back(m_comp.back());
m_comp.push_back(new Component());
m_icomp.push_back(m_comp.back());
}
// Impossible because it does not override the good method
virtual std::vector<IComponent*> &getComp()
{
std::cout << m_comp[0]->getDouble() << std::endl;
return m_icomp;
}

private:
// Duplicated storage for "nothing"
std::vector<Component*> m_comp;
std::vector<IComponent*> m_icomp;
};

在我看到的回复中,有关于实现 pop() 的内容和 push()方法,但在我的项目中,我使用的是 Map而不是 Collection ,并且有 block 的 vector 。这允许通过执行 map[y][x] 来访问 block .

问题是存储是固定的。一种解决方案是添加一个方法 getBlock(size_t x, size_t y)反而。但我想看看我能对第一个案例做的最好的事情:)

最佳答案

不确定此解决方案是否适用于您的情况,但是...将 Component 派生类作为模板参数传递给 ICollection 怎么样?

不完全是 Curiously Recurring Template Pattern,而是类似的东西。

我的意思是,像

template <typename CompT>
class ICollection
{
public:
virtual ~ICollection() {}

virtual std::vector<CompT*> &getComp() = 0;
};

所以Collection变成了

class Collection : public ICollection<Component>
{
public:
Collection()
{
m_comp.push_back(new Component());
m_comp.push_back(new Component());
}
virtual std::vector<Component*> &getComp()
{
return m_comp;
}

private:
std::vector<Component*> m_comp;
};

甚至,如果您在模板类中转换 Collection

template <typename CompT>
class Collection : public ICollection<CompT>
{
public:
Collection()
{
m_comp.push_back(new CompT());
m_comp.push_back(new CompT());
}
virtual std::vector<CompT*> &getComp()
{
return m_comp;
}

private:
std::vector<CompT*> m_comp;
};

关于接口(interface) ptr 的 C++ 返回 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42937457/

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