基于策略的设计——策略实现必须访问宿主类的成员

Posted

技术标签:

【中文标题】基于策略的设计——策略实现必须访问宿主类的成员【英文标题】:Policy based design - policy implementation has to access members of the host class 【发布时间】:2015-01-22 15:07:13 【问题描述】:

我认为解释我的问题的最好方法是使用一段代码:

class IncreasingMultiplier 

protected:

    IncreasingMultiplier(int initialMultiplier = 0, int incrementation = 1)

    int getMultiplier() 
        mCurrentMultiplier += mIncrementation;
        return mCurrentMultiplier - mIncrementation;
    

    void setMultiplier(int multiplier) 
        mCurrentMultiplier = multiplier;
    

    void setIncrementation(int incrementation) 
        mIncrementation = incrementation;
    

private:

    int mCurrentMultiplier;
    int mIncrementation;`



class ConstMultiplier 

protected:

    int getMultiplier() const 
        return 10;
    




class NumberLogger 

public:

    void log() 

        int currentNumber = getNumber(); // How can I call this method?

        std::cout << "Current number is " << currentNumber << std::endl;

    





template<

    class MultiplierPolicy,

    class LoggingPolicy

>
class Host : public MultiplierPolicy, public LoggingPolicy 

public:

    int getNumber() const 
        return mNumber * getMultiplier();

    

private:


    int mNumber;


基本上,一个策略可能需要访问宿主类中定义的成员,而这些成员又依赖于提供给宿主类的其他策略。

谢谢!

【问题讨论】:

在您的代码中,没有任何东西继承 NumberLogger 或调用它的成员函数。它与Host 类有什么关系?你需要给NumberLogger::log() 一个Host 实例来调用成员函数。 我想你应该看看CRTP。 【参考方案1】:

以下代码用VS2013编译(没有用GCC试过):

#include <iostream>

class IncreasingMultiplier 

protected:

    IncreasingMultiplier(int initialMultiplier = 0, int incrementation = 1)
        : mCurrentMultiplier(initialMultiplier)
        , mIncrementation(incrementation)
    

    int getMultiplier() 
        mCurrentMultiplier += mIncrementation;
        return mCurrentMultiplier - mIncrementation;
    

    void setMultiplier(int multiplier) 
        mCurrentMultiplier = multiplier;
    

    void setIncrementation(int incrementation) 
        mIncrementation = incrementation;
    

private:

    int mCurrentMultiplier;
    int mIncrementation;
;

class ConstMultiplier 

protected:

    int getMultiplier() const 
        return 10;
    

;

// Template the logger policy
// Unfortunately - couldn't get host inheritance CRTP pattern
// compiling in Visual Studio 2013 :(
// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
template < typename t_Host >
class NumberLogger /*: public t_Host*/ 

public:

    void log() 
        // This part of the CRTP pattern does work in Visual Studio 2013
        int currentNumber = static_cast<t_Host*>(this)->getNumber(); // How can I call this method?

        std::cout << "Current number is " << currentNumber << std::endl;
    

;

// Template based on a list of policies
template<
    typename PoliciesList
>
class Host : public PoliciesList::MultiplierPolicy, public PoliciesList::LoggingPolicy 

public:

    Host() : mNumber(1) 

    int getNumber() /*const*/ 
        return mNumber * getMultiplier();
    

private:

    int mNumber;
;

// Un-templated policies list
// Could create a macro to declare various policy combinations:
class ConcretePoliciesList_Const

public:
    typedef Host<ConcretePoliciesList_Const> MyHost;
    typedef ConstMultiplier MultiplierPolicy;
    typedef NumberLogger<MyHost> LoggingPolicy;
;

class ConcretePoliciesList_Increasing

public:
    typedef Host<ConcretePoliciesList_Increasing> MyHost;
    typedef IncreasingMultiplier MultiplierPolicy;
    typedef NumberLogger<MyHost> LoggingPolicy;
;

int main()

    ConcretePoliciesList_Const::MyHost const_host;
    ConcretePoliciesList_Increasing::MyHost increasing_host;

    std::cout << "Const policy:" << std::endl;
    const_host.log();
    const_host.log();
    const_host.log();

    std::cout << "Increasing policy:" << std::endl;
    increasing_host.log();
    increasing_host.log();
    increasing_host.log();

    return 0;

结果输出是:

Const policy:
Current number is 10
Current number is 10
Current number is 10
Increasing policy
Current number is 0
Current number is 1
Current number is 2

【讨论】:

以上是关于基于策略的设计——策略实现必须访问宿主类的成员的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之策略模式

设计模式之策略模式总结

为啥宿主机不能访问虚拟机

java学习-23种设计模式简述

k8s基于canel的网络策略

禁用 Firefox 同源策略