c++:如何避免 static_cast?

标签 c++ inheritance abstract static-cast

我有一个抽象基类和一个模板派生类。派生对象可以由派生对象的先前实例构造,比如说,一个整数。到目前为止,我们有

struct base {
  /* ...pure virtual functions here... */

  virtual ~base() = default;
  /* NO DATA */
};

template <class D>
struct derived : base {
  derived() = default;

  derived(int x, const derived& previous) {
    /* to construct I need access to previous.data_ */
  }

  /* ...overriden virtual functions here... */

  ~derived() = default;

  D data_;
};

请注意,派生类的构造函数需要访问 data_ previous的成员派生对象。现在我想创建一个函数来构造 derived<D> 类型的对象。通过将整数和 derived<D> 的先前实例作为输入, 并返回指向 base 的指针.问题是,自从 用户将使用 base类指针,函数应该 看起来像这样:

template <class D>
std::shared_ptr<base> getNext(int x, std::shared_ptr<base> current) {
  return std::make_shared<derived<D>>(x, *current); /* ERROR */
}

正如您可能已经猜到的那样,这会产生一个编译错误,表明没有来自 base 的已知转换至 derived<D> .我知道我可以使用的一件事是 static_cast<derived<D>&>(*current)因为底层对象的类型总是 derived<D> ,但理想情况下,我想尽可能避免任何强制转换。 任何想法如何克服这个问题>?提前致谢!

最佳答案

您可以在基类中使用虚拟访问器函数来指示派生类的类型。然后,您可以安全地使用 static cast 来强制转换基类。

class Animal {
    virtual bool isDog() { return false; }
    virtual bool isCat() { return false; }
};

class Dog : public Animal {
    virtual bool isDog() { return true; }
};

class Cat : public Animal {
    virtual bool isCat() { return true; }
};

然后我可以像这样安全地转换基类:

Dog A;
Cat B;

Animal *unknown_animal = &A;

if (unknown_animal->isDog()) {
    Dog *dog = static_cast<Dog*>(unknown_animal);
}
else if (unknown_animal->isCat()) {
    Cat *cat = static_cast<Cat*>(unknown_animal);
}

如果您只需要知道派生类型,但不需要访问它,访问器函数也很有用。

关于c++:如何避免 static_cast?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19452162/

相关文章:

c# - 为什么有些人将大括号放在与语句相同的行,而另一些人则另起一行?

c# - .NET 并发集合可以用于 x32 到 x64 的进程间通信吗?

c++ - catch 语句中可以发生复制省略吗?

python - 为什么属性引用在 Python 继承中会这样?

向多个类添加多个方法的 Pythonic 方式?

java - 如何使用反射访问从抽象类继承的字段?

c++ - 如何使 clang-format 11 在可变参数模板声明后放置一个空格

java - 我如何限制使用它们的子类的抽象类中的方法参数?

css - 将类属性添加到 symfony 表单生成器行 div

java - 将抽象类存储在数组列表中