【发布时间】:2023-03-28 20:18:02
【问题描述】:
昨天,我写了一些代码,如果这是好的还是坏的做法,我真的很感激。如果它不好,可能会出什么问题。
构造如下:
可悲的是,基类 A 作为模板来自 API。目标是能够将 A 的派生类放入 std::vector 中。我通过基类 B 实现了这一点,从 A 继承的所有派生类都将从该基类继承。如果没有 B 中的纯虚函数,则会调用 A 中的 foo() 函数。
使用 B 中的纯虚函数,调用 C 中的 foo() 版本。这正是我想要的。
那么这是不好的做法吗?
编辑:
为了消除我的示例代码中的一些误解:
template <class T>
class A
{
public:
/* ctor & dtor & ... */
T& getDerived() { return *static_cast<T*>(this); }
void bar()
{
getDerived().foo(); // say whatever derived class T will say
foo(); // say chicken
}
void foo() { std::cout << "and chicken" << std::endl; }
};
class B : public A<B>
{
public:
/* ctor & dtor */
virtual void foo() = 0; // pure-virtual
};
class C : public B
{
public:
/* ctor & dtor */
virtual void foo() { std::cout << "cow"; }
};
class D : public B
{
public:
/* ctor & dtor */
virtual void foo() { std::cout << "bull"; }
};
std::vector 应该同时包含 C 和 D 和
void main()
{
std::vector<B*> _cows;
_cows.push_back((B*)new C()));
_cows.push_back((B*)new D()));
for(std::vector<B*>::size_type i = 0; i != _cows.size(); ++i)
_cows[i].bar();
}
有输出
cow and chicken
bull and chicken
是需要的。
据我所知,除了使用基类之外,没有其他方法可以将派生自模板类的类存储在容器中。如果我为派生类使用基类,例如,B 我必须将向量中的每个实例转换回其正确的类。但是在调用 bar() 时,我不知道确切的类型。
【问题讨论】:
-
基类中没有虚拟析构函数。
-
你在 B 中隐藏了 void A::foo()。在 A 中它不是虚拟的
-
@spiritwolfform 好的,但这是一种不好的做法吗?会出什么严重的问题吗?是的,没有虚拟析构函数,因为这是一个外卖,而不是原始代码。
-
这意味着你现在有两个方法,所以你可以用
_cows[0].foo()来打印cow和_cows[0].A<B>::foo()来打印chicken,这是两个独立的方法 -
@kronos:当您使用主要用于静态多态性的 CRTP 时,为什么要使用
virtual函数? stackoverflow.com/questions/262254/…
标签: c++ inheritance overwrite crtp pure-virtual