如何在C++项目中实现封装



我目前正在学习OOP设计模式,我正在从事一个项目,该项目的主要课程大致组织如下:

class MainClass {
public:
MainClass(int something, CrazyTypeOfAlgorithm algoType);
double getResult();

private:
std::vector<double> _numbers;
CrazyTypeOfAlgorithm _algoType;
};

其中CCD_ 1是枚举。基本上,根据所使用的特定算法,getResult()函数相应地起作用。到目前为止,我一直在后者的实现中使用简单的switch语句。当引入更多的算法时,这个类会增长很多,我想以某种方式将算法封装在它自己的类中。我尝试实现策略模式,但最终遇到的问题是,实现不同算法的类需要是MainClass的朋友类,因为它们需要访问MainClass的私有成员变量(例如_numbers(。在这种情况下,我将如何实现正确和干净的封装?

一种常见的方法是使Algorithm成为一个具有各种实现(如下面的AlgorithmSimpleSum(的纯虚拟(接口(类,有点像这样:

// Pure Virtual Interface
class Algorithm
{
public:
virtual ~Algorithm() = default;
virtual double process(double const* begin, double const* end) const = 0;
};
class MainClass {
public:
MainClass(std::vector<double> const& numbers, std::unique_ptr<Algorithm> algorithm)
: numbers(numbers), algorithm(std::move(algorithm)) {}
double getResult() { return algorithm->process(numbers.data(), numbers.data() + numbers.size()); }
private:
std::vector<double> numbers;
std::unique_ptr<Algorithm> algorithm;
};
// Concrete implementation of an Algorithm
class AlgorithmSimpleSum
: public Algorithm
{
public:
double process(double const* begin, double const* end) const override
{
double r = 0.0;
while(begin != end)
r += *begin++;
return r;
}
};

您可以将Algorithm::process()函数的参数设置为std::vector<double> const&,但这有点不通用/灵活,尽管它具有更简单的优点。

protected继承和成员是一个选项:

class MainClass {
public:
MainClass(int something, CrazyTypeOfAlgorithm algoType);
double getResult();

protected:
std::vector<double> _numbers;
CrazyTypeOfAlgorithm _algoType;
};
class Algorithm1 : protected MainClass {
public:
using MainClass::MainClass;
// option 1
using MainClass::getResult();
// option 2
double getResult() { return 42; }
};
template <CrazyTypeOfAlgorithm AType>
auto factory(int something) {
if constexpr (AType == CrazyTypeOfAlgorithm::A1) return Algorithm1(something, AType);
// more cases ...
}

最新更新