我有 4 个类:Foundation
, FoundationWidget
, Game
和 GameWidget
. FoundationWidget
延伸Foundation
和 GameWidget
延伸Game
.
Game
还包含一个 std::array of Foundation
s 和 GameWidget
包含一个 std::array of FoundationWidget
秒。 Game
还包含一个虚拟方法,它应该返回指向 Foundation
数组的指针秒。 GameWidget
通过返回指向其 FoundationWidget
的数组的指针来覆盖此方法秒。
当前(非工作)实现如下所示:
class Game {
std::array<Foundation, 4> foundations;
private:
virtual std::array<Foundation, 4>* get_foundations() {
return &this->foundations;
}
}
class GameWidget : public Game {
std::array<FoundationWidget, 4> foundations;
private:
std::array<Foundation, 4>* get_foundations() {
return &this->foundations;
}
}
我希望它能工作,因为它是一个与类大小相同的数组,它扩展了指定为返回类型的数组,但我收到了这个错误:cannot convert ‘std::array<FoundationWidget, 4ul>*’ to ‘std::array<Foundation, 4ul>*’ in return
.
我也尝试过将类属性声明为指针数组,但结果是一样的。 static_cast 或 dynamic_cast 都没有帮助。
我在这里错过了什么?有没有办法转换数组?如果不是,我可以使用一些构造来获得相同的结果,即“虚拟”类(class)成员吗?
最佳答案
数组是某种数据类型的压缩值。
不同类型的数组作为数组不兼容。例如,它们的大小可以不同。并且数组是打包的,因此大小为 7 的元素数组和大小为 8 的元素数组将不起作用。
即使它们的大小相同,C++ 也规定数组不可转换。
您可以通过 array<unique_ptr<Base>, N>
来解决这个问题--(智能)指针数组。也可以写一个类型删除 any_derived<Base, size_limit>
输入并得到一个 array<any_derived<Base, size_limit>, N>
如果您想避免额外的碎片和分配,并连续存储它们。
但实际上只使用unique_ptr
.
using foundations_t = std::array<std::unique_ptr<Foundation>, 4>;
template<class T> struct tag_t {};
struct HasFoundation {
foundations_t foundations;
HasFoundation( tag_t<T> ) {
std::generate(foundations.begin(), foundations.end(), []{return std::make_unique<T>(); } );
}
HasFoundation(HasFoundation const&)=delete;
HasFoundation(HasFoundation&&)=default;
HasFoundation& operator=(HasFoundation const&)=delete;
HasFoundation& operator=(HasFoundation&&)=default;
};
class Game:HasFoundation {
protected:
template<class T>
Game(tag_t<T> tag):HasFoundation(tag){}
public:
Game():Game(tag_t<Foundation>{}) {}
virtual foundations_t* get_foundations() {
return &this->foundations;
}
};
class GameWidget : public Game {
public:
GameWidget():Game(tag_t<FoundationWidget>{}) {}
};
这里我们有一个存储类,它存储的内容是在构造时确定的。
模板版本需要 Game
中的所有逻辑暴露在头文件中。这个反而要求所有访问 foundations
的“真实”类型元素需要运行时分派(dispatch)。
关于C++ std::array 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43762801/