加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将函数注入子类

发布时间:2020-12-16 07:12:05 所属栏目:百科 来源:网络整理
导读:是否可以在C 14中执行此类操作.我有一个基类如下: #include iostreamclass AbstractElement;class ConcreteElement;class SuperConcreteElement;class B{public: void bar(AbstractElement*) { std::cout "Abstract element" std::endl; } void bar(Concret
是否可以在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中看到的那样,函数的主体完全相似.但由于依赖于静态类型,我无法将其移动到基类中.尽管如此,每次我需要添加一个AbstractElement的子类时,我不想写完全相同的代码.所以,我需要某种机制,为我们提供将代码注入函数的工具.

只要马科斯不是非常理想的解决方案,我想问一下在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类,我们可以将指向基类的指针强制转换为指向派生类的指针.从而解决了代码重复的问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读