是否可以在 C++14
中做这样的事情。我有一个基类如下:
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
class ConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //1
}
};
class SuperConcreteElement : public AbstractElement
{
private:
B _b;
public:
void foo()
{
_b.bar(this); //2
}
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
正如您在 //1
和 //2
中看到的,函数的主体完全相似。但是我不能完全将它移动到基类中,因为取决于 this
的静态类型。尽管如此,每次我需要添加 AbstractElement
的子类时,我都不想编写完全相同的代码。因此,我需要某种机制来为我们提供将代码注入(inject)函数的便利。
只要 marcos 不是非常理想的解决方案,我想问一些可以在 C++14
中完成的技巧来解决这样的问题。
最佳答案
是的,可以使用 CRTP :
#include <iostream>
class AbstractElement;
class ConcreteElement;
class SuperConcreteElement;
class B
{
public:
void bar(AbstractElement*)
{
std::cout << "Abstract element" << std::endl;
}
void bar(ConcreteElement*)
{
std::cout << "Concrete element" << std::endl;
}
void bar(SuperConcreteElement*)
{
std::cout << "Super concrete element" << std::endl;
}
};
class AbstractElement
{
public:
virtual void foo() = 0;
};
template <class T>
class CRTPAbstractElement : public AbstractElement
{
B _b;
public:
virtual void foo()
{
T* t = dynamic_cast<T *>(this);
_b.bar(t);
}
};
class ConcreteElement : public CRTPAbstractElement<ConcreteElement>
{
};
class SuperConcreteElement : public CRTPAbstractElement<SuperConcreteElement>
{
};
int main()
{
AbstractElement *e = new ConcreteElement();
e -> foo(); //Prints Concrete element
}
通过添加中间 CRTP 类,我们能够将指向基类的指针转换为指向派生类的指针。从而解决代码重复的问题。
关于c++ - 将函数注入(inject)子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30010716/