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