c++ - 是否存在针对新成员的编译器强制执行完整性的模式?

标签 c++ compilation

想象一个更大的项目,包含一些参数结构:

struct pars {
    int foo;
};

以这个结构体作为参数,实现其他功能,例如:

// (de)serialization into different formats
static pars   FromString(string const &text);
static string ToString(pars const &data);
static pars   FromFile(string const &filename);
// [...]

// comparison / calculation / verification
static bool   equals(pars l, pars r);
static pars   average(pars a, pars b);
static bool   isValid(pars p);
// [...]

// you-name-it

现在假设需要向该结构添加一个新成员:

struct pars {
    int foo;
    int bar; // new member
};

是否有一种设计模式可以中断构建或发出警告,直到调整所有必要的代码位置?

示例:

  • 如果我将 int foo 更改为 string foo,我将不会错过任何需要更改的代码行。
  • 如果 int foo 需要更改为 unsigned int foo,我可以将 foo 重命名为 foo_u 并且让编译器指出需要调整的地方。

一个部分解决方案是使成员私有(private)并且只能从构造函数中设置,必须使用所有参数调用:

pars::pars(int _foo, int _bar)
 : foo(_foo), bar(_bar)
{ }

这确保了 pars 的正确创建,但不是使用 - 所以这会在 FromString() 中捕获缺失的改编,但在ToString().

单元测试只会在测试期间(我正在搜索编译时方法)和(反)序列化部分揭示此类问题,而不是正在考虑新的 bar无处不在(在比较/计算/验证/...功能中也是如此)。

最佳答案

将流操作与流的源或目标分离。

一个非常简单的例子:

#include <sstream>
#include <fstream>

struct pars
{
    int foo;
    int bar;

    static constexpr auto current_version = 2;
};

std::istream &deserialise(std::istream &is, pars &model)
{
    int version;

    is >> version;
    is >> model.foo;
    if (version > 1) {
        is >> model.bar;
    }
    return is;
}

std::ostream &serialise(std::ostream &os, const pars &model)
{
    os << model.current_version << " ";
    os << model.foo << " ";
//    a version 2 addition
    os << model.bar<< " ";
    return os;
}

static pars FromString(std::string const &text)
{
    std::istringstream iss(text);
    auto result = pars();
    deserialise(iss, result);
    return result;
}

static std::string ToString(pars const &data)
{
    std::ostringstream oss;
    serialise(oss, data);
    return oss.str();
}

static pars FromFile(std::string const &filename)
{
    auto file = std::ifstream(filename);
    auto result = pars();
    deserialise(file, result);
    return result;
}

另请参阅:

boost.serialization http://www.boost.org/doc/libs/1_64_0/libs/serialization/doc/index.html

Cereal https://github.com/USCiLab/cereal

等等

关于c++ - 是否存在针对新成员的编译器强制执行完整性的模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46363526/

相关文章:

android - 编译 AOSP 错误 : make: [out/build-aosp_arm. 忍者] 被杀死

c - 为什么按位或不会产生常量表达式,但加法会

c++ - 不用g++编译c代码的主要原因是什么?

c++ - Boost 程序选项和 shared_ptr

c++ - 使用 malloc 进行动态内存分配

c++ - 检测碰撞球体的程序出错

c++ - 多线程 curl 请求的段错误

C++ 在数组或字符串中插入字符

c++ - 增加字符串文字长度限制

C++ 程序行为取决于源代码文件集