gpt4 book ai didi

c++ - C++中的策略模式。实现方案

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:51:41 24 4
gpt4 key购买 nike

这是一个简化的示例,称为(我希望 - 如果我错了,请纠正我)Strategy 模式:有一个类 FileWriter它将键值对写入文件并使用 IFormatter 的对象用于格式化正在编写的文本的界面。有不同的格式化程序实现,当 FileWriter 时传递格式化程序对象。被 build 。这是这种模式的一个(错误的)实现:

#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <sstream>

using namespace std;

class IFormatter {
public:
virtual string format(string key, double value) = 0;
};

class JsonFormatter : public IFormatter {
public:
string format(string key, double value) {
stringstream ss;
ss << "\""+key+"\": " << value;
return ss.str();
}
};

class TabFormatter : public IFormatter {
public:
string format(string key, double value) {
stringstream ss;
ss << key+"\t" << value;
return ss.str();
}
};

class FileWriter {
public:
FileWriter(string fname, IFormatter& fmt):fmt_(fmt)
{
f_.open(fname.c_str(), ofstream::out);
}

void writePair(string key, double value)
{
f_ << fmt_.format(key, value);
}

private:
ofstream f_;
IFormatter& fmt_;
};

可以看出,这种方法的主要缺点是不可靠 - Formatter对象传递给 FileWriter必须存在于整个 FileWriter 期间的生命周期,因此调用 FileWriter("test.txt", JsonFormatter())直接导致SegFault .

在这方面,我想讨论实现这种具有“易于使用”和简单性要求的方法的其他选择:

  • 可以在创建文件编写器时传递新的格式化程序,或者
  • 可以传递和使用现有的格式化程序。

我想出了下面描述的几种替代方案及其缺点(IMO):

  • 模板FileWriter作为模板类,它采用精确的 FormatterClass作为论点; 缺点:很难调用:FileWriter<JsonFormatter>("test.txt", JsonFormatter()) - 这里,JsonFormatter被打了两次。
  • 原始指针: FileWriter("test.txt", new JsonFormatter()) ; 缺点 - 谁应该删除格式化程序对象? FileWriter ?如果是,则传递现有格式化程序的地址将导致 SegFault一次FileWriter对象尝试删除格式化程序。
  • 共享指针: FileWriter("test.txt", dynamic_pointer_cast<IFormatter*>(shared_ptr<JsonFormatter*>(new JsonFormatter())) ; 缺点:很难调用,而且,如果在创建文件编写器之前创建了格式化程序怎么办?

此处的最佳做法是什么?

更新

回应建议使用 std::function 的答案- 如果 Formatter 可以存储一个状态(比如精度)并有其他方法,比如 getHeader() 会怎么样? ,例如,对于 CSV 文件?

此外,存储 IFormatter按值是不可能的,因为它是一个抽象类。

最佳答案

最简单的解决方案是使用:

JsonFormatter formatter;
FileWriter writer("test.txt", formatter);
// Use writer.

另一个更好一点的选择是在 IFormatter 中有一个 clone() 函数。然后,FileWriter 可以克隆该对象,取得克隆的所有权并在其析构函数中将其删除。

 class IFormatter {
public:
virtual string format(string key, double value) = 0;
virtual IFormatter* clone() const = 0;
};


class FileWriter {
public:

FileWriter(string fname, IFormatter const& fmt):fmt_(fmt.clone())
{
f_.open(fname.c_str(), ofstream::out);
}

~FileWriter()
{
delete fmt_;
}

void writePair(string key, double value)
{
f_ << fmt_->format(key, value);
}

private:
ofstream f_;
IFormatter* fmt_;
};

现在,您也可以使用临时对象调用 FileWriter

FileWriter writer("test.txt", JsonFormatter());
// Use writer.

关于c++ - C++中的策略模式。实现方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35952765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com