基于策略的设计——策略实现必须访问宿主类的成员
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
【讨论】:
以上是关于基于策略的设计——策略实现必须访问宿主类的成员的主要内容,如果未能解决你的问题,请参考以下文章