c++ - 将函数注入(inject)子类

标签 c++ overloading

是否可以在 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/

相关文章:

c++ - 二维数组如何存储在内存中?

c++ - 函数重载: builtin vs user defined types

c++ - 如何选择适合 C++ 的重载函数?

c++ - 赋值运算符重载未被调用

c++ - 是否可以知道整数类型有多少位?

c++ - 使用来自另一个类 SFML c++ 的函数时,Sprite 不会移动

c++ - 为什么在重新分配小块内存时分配大块内存失败

c++ - C++中使用字符串指定文件路径(将文件存放在文件夹中)

java - 为什么 Java 在重载方法时会有这样的行为?

c++ - 将函数定义为静态成员和自由成员之间有什么区别?