【问题标题】:c++ array of templated abstract-base-class without breaking strict-aliasing rulec++ 模板化抽象基类数组,不违反严格别名规则
【发布时间】:2018-11-30 18:07:16
【问题描述】:

在不违反严格别名规则的情况下,创建从抽象模板基类派生的对象数组的最佳方法是什么?每个派生对象都会以不同的方式定义基类的模板参数,但只能通过常量枚举值。这是一个例子

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

}

【问题讨论】:

  • 具有不同实际类型参数的实例是不同的类,彼此无关(通过继承或任何其他关系),尽管有共同的模板名称。

标签: c++ arrays inheritance strict-aliasing template-classes


【解决方案1】:

这里的问题是class B : public A&lt;int, BlaEnum::Bla2&gt;class C : public A&lt;int, BlaEnum::Bla3&gt; 派生自彼此不兼容的不同A。这些类中的每一个都会导致一个新模板类的实例化(它们都不兼容A&lt;int&gt;)。

为了拥有有效的公共基础,您需要一个与派生类在任何模板参数(或者是非模板类)上都没有区别的基类。
修改您的示例,例如:

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(或 std::vector)和智能指针而不是原始指针

【讨论】:

    猜你喜欢
    • 2017-02-25
    • 1970-01-01
    • 2020-04-11
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多