c++ - c++ 模板化抽象基类数组,不违反严格别名规则
问题描述
在不违反严格别名规则的情况下,创建从抽象模板基类派生的对象数组的最佳方法是什么。每个派生对象都会以不同的方式定义基类的模板参数,但只能通过常量枚举值。这是一个例子
enum BlaEnum
{
Bla1,
Bla2,
Bla3
};
template <class T, BlaEnum bla = Bla1>
class A
{
public:
virtual void Foo() = 0;
T att;
BlaEnum bll;
};
class B : public A<int, BlaEnum::Bla2>
{
public:
void Foo() override;
};
class C : public A<int, BlaEnum::Bla3>
{
public:
void Foo() override;
};
int main(void)
{
B b;
C c;
//violates strict-aliasing rule
A<int>* BaseArr[2] = { (A<int>*)&b,(A<int>*)&c };
}
解决方案
这里的问题是,class B : public A<int, BlaEnum::Bla2>
并且class C : public A<int, BlaEnum::Bla3>
源自A
彼此不兼容的不同。这些类中的每一个都会导致一个新模板类的实例化(它们都不兼容A<int>
)。
为了拥有有效的公共基础,您需要一个与派生类在任何模板参数(或者是非模板类)方面都没有区别的基类。
修改您的示例,例如:
template <class T>
class Base
{
public:
virtual void Foo() = 0;
};
template <class T, BlaEnum bla = Bla1>
class A : public Base<T>
{
public:
T att;
BlaEnum bll;
};
// B and C are unchanged
int main()
{
B b;
C c;
// Array of pointers to common base class
Base<int>* BaseArr[2] = { &b,&c };
}
还有一点需要注意:C 风格的数组不是一个好习惯,您应该更喜欢std::array
(or std::vector
) 和智能指针而不是原始指针
推荐阅读
- nginx - 可以在 Nginx conf 文件中清楚地写 IP 地址吗?
- c++ - 如何对仅删除连续重复项的字符串进行重复数据删除
- python - 每周队列,python pandas,sql
- sql-server - SQL Server 2017 vs SQL Server 2012 性能问题
- java - javascript 错误:无法在“文档”上执行“elementsFromPoint”:提供的双精度值是非有限的
- instagram - 从 instaloader 下载 1 周数据
- python - 如何计算多个数据帧之间的重叠行?
- javascript - 如何阻止空输入字段影响javascript计算
- angular - 文件上传已被 CORS 策略阻止
- regex - 正则表达式提取 URL 的字母数字部分?