【问题标题】:How create few objects with CRTP?如何使用 CRTP 创建少量对象?
【发布时间】:2019-10-21 14:05:35
【问题描述】:

我编写了一个小示例 CRTP 模式以更好地学习它并在更复杂的代码中使用它。 我想使用 CRTP,该基类可以访问派生类。好的,但我不能为我的基类创建几个对象。如果我首先为两个对象 Base<Derived1> base1; Base<Derived2> base2; 调用构造函数,然后在第二次调用每个对象 base1.PrintDerived_FromA(); base2.PrintDerived_FromA(); 的函数时,我有结果:

Base constr work
Base constr work
b_: 0
b_: 25

但是,我应该有那个:

Base constr work
Base constr work
b_: 9
b_: 25

如果我在构造函数之后调用函数,一切OK:

Base<Derived1> base1;
base1.PrintDerived_FromA();
Base<Derived2> base2;
base2.PrintDerived_FromA();

结果:

Base constr work
b_: 9
Base constr work
b_: 25

结果是一个新的构造函数调用覆盖了现有对象,但为什么呢?有可能解决这个问题吗?而且我只想使用 CRTP,没有虚拟功能。

#include <iostream>

template <class T>
class Base {
 public:
  Base();
  void PrintDerived_FromA();
  void InitializeDerived();
};

class Derived1 : public Base<Derived1> {
 public:
  Derived1(int b);
  void PrintDerived();
  void SetDerived(int b);

 private:
  int b_;
};

class Derived2 : public Base<Derived2> {
 public:
  Derived2(int b);
  void PrintDerived();
  void SetDerived(int b);

 private:
  int b_;
};


template <typename T>
Base<T>::Base() {
  InitializeDerived();
  std::cout << "Base constr work" << std::endl;
}

template <>
void Base<Derived1>::InitializeDerived() {
  static_cast<Derived1*>(this)->SetDerived(9);
}

template <>
void Base<Derived2>::InitializeDerived() {
  static_cast<Derived2*>(this)->SetDerived(25);
}

template <typename T>
void Base<T>::PrintDerived_FromA() {
  static_cast<T*>(this)->PrintDerived();
}


Derived1::Derived1(int b) : b_(b), Base() {
  std::cout << "Derived1 constr work" << std::endl;
}

void Derived1::PrintDerived() {
  std::cout << "b_: " << b_ << std::endl;
}

void Derived1::SetDerived(int b) {
  b_ = b;
}


Derived2::Derived2(int b) : b_(b), Base() {
  std::cout << "Derived2 constr work" << std::endl;
}

void Derived2::PrintDerived() {
  std::cout << "b_: " << b_ << std::endl;
}

void Derived2::SetDerived(int b) {
  b_ = b;
}


int main() {
  Base<Derived1> base1;
  Base<Derived2> base2;

  base1.PrintDerived_FromA();
  base2.PrintDerived_FromA();

  return 0;
}

【问题讨论】:

    标签: c++ templates crtp


    【解决方案1】:

    static_cast&lt;Derived1*&gt;(this) 转换无效:this 指向 Base&lt;Derived1&gt; 类型的对象而不是 Derived1。所以取消引用产生的指针会导致未定义的行为。为了让 CRTP 工作,您需要创建派生类的对象。

    【讨论】:

      猜你喜欢
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-04
      • 2012-03-01
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      相关资源
      最近更新 更多