gpt4 book ai didi

c++ - 在旧代码中以最少的更改创建基于类型的标识号

转载 作者:太空宇宙 更新时间:2023-11-04 11:28:36 24 4
gpt4 key购买 nike

我正在维护一个非常古老(20 多年)且相当大(15 KLOC)的库,其中包含各种类型的对象,这些对象当前由整数标识。这就提出了一个问题,即仅给出整数我就不知道它应该识别哪种类型的对象。这在编译时会非常好。

我想出的解决方案只有最少的改动,即创建一个 ID 模板,然后为各种类型的对象 ID 创建 typedef。

我意识到我必须向模板添加第三个参数,因为我认为两个完全不同的标识符可能具有相同的基础类型和范围。

我发现C++没有考虑

typedef int X;
typedef int Y;

作为完全不同的类型。

这是解决方案吗:-

A)合理(我知道它有效)

B) 是否有另一种简单的方法来做到这一点 - 管理层害怕高 LOC 变化

仅使用示例运算符简化解决方案。

#include <iostream>

// Horrible old definition of current code
class OldObjectA
{
public:
int ident_; // int identifier
int uniq_; // another int identifier unique to OldObjectA's only
};

class OldObjectB
{
public:
int ident_;
int next_; // int of another OldObjectB ident_
int uniq_; // another int identifier unique to OldObjectB's only
int dq_; // int of yet anothera OldObjectB ident_
int com_; // int of ident_ of a OldObjectA
int ld_; // int of ident_ of a OldObjectC
};

class OldObjectC
{
public:
int indent_;
int next_; // int of another OldObjectC ident_
int com_; // int of ident_ of a OldObjectA
};

enum Type { TypeA, TypeAU, TypeB, TypeBU, TypeC };

template<class T, T maxval, Type type>
class ID
{
public:
friend bool operator==(const ID<T, maxval, type> &lhs, const ID<T, maxval, type> &rhs)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
return true;
}
};

typedef ID<int, 42, TypeA> ID_A;
typedef ID<int, 42, TypeAU> ID_UniqA;
typedef ID<int, 42, TypeB> ID_B;
typedef ID<int, 42, TypeBU> ID_UniqB;
typedef ID<int, 100, TypeC> ID_C;

// What I was thinking of doing
class NewObjectA
{
public:
ID_A ident_; // int identifier
ID_UniqA uniq_; // another int identifer
};

class NewObjectB
{
public:
ID_B ident_;
ID_B next_; // int of another OldObjectB ident_
ID_UniqB uniq_; // another int
ID_B dq_; // int of yet anothera OldObjectB ident_
ID_A com_; // int of ident_ of a OldObjectA
ID_C ld_; // int of ident_ of a OldObjectC
};

class NewObjectC
{
public:
ID_C indent_;
ID_C next_; // int of another OldObjectC ident_
ID_A com_; // int of ident_ of a OldObjectA
};

int main(int argc, char *argv[])
{
std::cout << "================================================================================\n";
ID_A a,a2;
ID_UniqA au,au2;
ID_B b,b2;
ID_UniqB bu,bu2;
ID_C c,c2;

a==a2;
au==au2;
b==b2;
bu==bu2;
c==c2;

// wanted and expected compile time fails
// a=au;
// a=b;
// a=bu;
// a=c;
// au=b;
// au=bu;
// au=c;
// b=bu;
// b=c;

std::cout << "================================================================================\n";


return 0;
}

最佳答案

添加模板参数以区分其他相同类型的想法是合理的。这是一种有用的技术,每隔一段时间就会出现一次。最近,我使用了类似的技术来定义测量类型(即公里、升、秒等)。

您至少可以对现有内容进行一种简化。枚举不是必需的。您可以在其 ID 定义中使用类型本身。

template<class T, T maxval, class tag>
struct ID {
};

template<class T, T maxval, class tag>
bool operator==(ID<T, maxval, tag> lhs, ID<T, maxval, tag> rhs)
{
return true;
}

typedef ID<int, 42, class NewObjectA> ID_A;
typedef ID<int, 42, class NewObjectB> ID_B;

struct NewObjectA {
ID_A id;
};

struct NewObjectB {
ID_B id;
};

void f()
{
ID_A id_a;
ID_B id_b;

id_a == id_a;
id_b == id_b;
//id_a == id_b; // won't compile as expected
}

这样做的好处是不用在一个地方创建程序中所有类型的全局列表。如果您需要根据继承层次结构允许的转换来处理 ID,使用类型本身也可以使事情变得更容易。例如,ObjectC 是 ObjectA,因此 ID_C 可转换为 ID_A。

我发现通过添加这种东西(我正在做的测量是相似的),增量方法通常是可行的方法。每次您需要接触一段代码时,都会在本地引入一些改进,并在进行更多更改之前确认它们按预期工作。如果您认为您已经识别出错误并改变了程序行为,那么测试这些更改就尤为重要。相比之下,试图一次性改变所有事情往往会带来很多痛苦。

关于c++ - 在旧代码中以最少的更改创建基于类型的标识号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12791812/

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