使用CRTP时,如何调用派生类的构造函数
How can I call the constructor of the derived class when using CRTP?
我有以下设置:
#include <iostream>
template <typename T>
struct feline {
void roar() noexcept {
static_cast<T*>(this)->do_roar();
}
feline() noexcept {
std::cerr << "Feline ctor" << std::endl;
}
};
struct lion : public feline<lion> {
lion() noexcept : feline() {
std::cerr << "Lion ctor" << std::endl;
}
void do_roar() noexcept {
std::cerr << "Lion roar" << std::endl;
}
};
struct tiger : public feline<tiger> {
tiger() noexcept : feline() {
std::cerr << "Tiger ctor" << std::endl;
}
void do_roar() noexcept {
std::cerr << "Tiger roar" << std::endl;
}
};
int main()
{
feline<lion> lion;
lion.roar();
feline<tiger> tiger;
tiger.roar();
}
当我执行它时,我会得到以下结果:
Feline ctor
Lion roar
Feline ctor
Tiger roar
这意味着狮子和老虎的构造源从未被调用。我该如何实现?
因为您永远不会创建实际的狮子。
CRTP需要实际类的对象才能正常工作。
请记住,基类永远不会直接实例化儿童班,因为这一切都涉及迫使该类支持某些功能而不是经典的继承。
您的代码可能会崩溃,但不会崩溃,这是因为函数do_roar
无法访问任何私人变量。尝试将一些成员添加到lion
并在do_roar
中使用它们,您会看到...
如果您想要狮子使用lion
类,则feline<lion>
只是feline<T>
的实例化,其中T = lion
。
您使用的是CRTP略有错误。片刻,忘记了基类是在继承类中参数化的事实,那么您的工作就是:
struct feline { };
struct lion : feline {};
feline roary; // in your actual code this is parametrized with lion
// but still it is no lion !
当您真正想创建狮子时:
lion roary; // this is a lion !
您声明了新类,但没有使用它们。
以下是使用新类的修订main()
:
int main()
{
lion l;
l.roar();
tiger t;
t.roar();
}
输出:
Feline ctor
Lion ctor
Lion roar
Feline ctor
Tiger ctor
Tiger roar
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 调用派生类成员函数
- 从基类实例调用派生类方法而不进行强制转换
- 从基类 (C++) 调用派生类中的非虚函数
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何从 Gtk::窗口调用派生对象的析构函数
- 在dynamic_pointer_cast后调用派生类的构造函数
- 从 Base 引用对象调用派生类的成员
- 有没有办法在没有虚拟的情况下使用基类指针调用派生类函数
- 在 c++ 中,如何使用向量调用派生类?
- C++通过 const 引用传递时不调用派生类函数
- 哪个基类调用派生重写的方法?
- 如何从包含基类指针的容器中调用派生类函数(基于其类型)?
- 如何调用派生类之一
- 从基类数组调用派生函数
- 从具有泛型返回类型的 crtp 基类调用派生类中的函数
- 基类如何调用派生类在 c++ 中传递的闭包?
- 通过在基类中虚拟调用派生类中的函数来访问派生类中的函数
- 如何在另一个类的向量中调用派生类的析构函数
- 通过reinterpret_casting方法指针从指针调用派生类的方法。这是 UB 吗?