Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 更改遗留代码的类层次结构_C++_Refactoring - Fatal编程技术网

C++ 更改遗留代码的类层次结构

C++ 更改遗留代码的类层次结构,c++,refactoring,C++,Refactoring,如果一个类在软件中已经存在了10多年,并且被广泛使用,那么改变该类的类层次结构是否有任何不利之处? 我有一个a类,它不继承任何东西。我想做的是使它从一个新的抽象基类继承,并将其当前的2个方法更改为虚拟方法。 我通常会这么做,但我的同事更不情愿,所以这可能会导致什么问题呢? 谢谢 编辑: 我想这样做的原因是: 我们正在创建一个新模块,它可以将旧类a或新创建的类B作为源。 所以我正在考虑创建一个抽象类SourceofX,类A和B将从中继承。 多态性将仅由采用SourceofX对象的新类/方法使用。

如果一个类在软件中已经存在了10多年,并且被广泛使用,那么改变该类的类层次结构是否有任何不利之处? 我有一个a类,它不继承任何东西。我想做的是使它从一个新的抽象基类继承,并将其当前的2个方法更改为虚拟方法。 我通常会这么做,但我的同事更不情愿,所以这可能会导致什么问题呢? 谢谢

编辑: 我想这样做的原因是:

我们正在创建一个新模块,它可以将旧类a或新创建的类B作为源。 所以我正在考虑创建一个抽象类SourceofX,类A和B将从中继承。 多态性将仅由采用SourceofX对象的新类/方法使用。
如果您有比这更好的想法,我洗耳恭听

更改旧代码时总是有风险的。其中大部分是你无法预见的

大多数情况下,原因是其他人所做的黑客错误修复,并有机地成为软件的一部分。现在它已经稳定了,这些黑客补丁可能引入了一些其他的bug,并导致了一些修复这些bug的黑客补丁。这个软件已经有10年的历史了,所以我保证有这样的修复程序

就我个人而言,即使是旧代码中最小的更改,我也会非常小心。引入新的继承级别并不是一个小的代码更改。所以是的,这是非常危险的

高级分析只会指出设计问题,但留给您的问题只会出现在测试中。如果这段代码有所有者,去问他。然后,再问他一次。打扰他,在你找到东西之前不要停下来

我的建议是,如果您还没有单元测试,那么就编写单元测试,在这种情况下-完美地测试该类中的s&%t,孩子们。。。嗯,一切都好


之后,编写更多的单元测试。多次运行测试。在多个平台上。在晚上。周三。

更改旧代码时总是存在风险。其中大部分是你无法预见的

大多数情况下,原因是其他人所做的黑客错误修复,并有机地成为软件的一部分。现在它已经稳定了,这些黑客补丁可能引入了一些其他的bug,并导致了一些修复这些bug的黑客补丁。这个软件已经有10年的历史了,所以我保证有这样的修复程序

就我个人而言,即使是旧代码中最小的更改,我也会非常小心。引入新的继承级别并不是一个小的代码更改。所以是的,这是非常危险的

高级分析只会指出设计问题,但留给您的问题只会出现在测试中。如果这段代码有所有者,去问他。然后,再问他一次。打扰他,在你找到东西之前不要停下来

我的建议是,如果您还没有单元测试,那么就编写单元测试,在这种情况下-完美地测试该类中的s&%t,孩子们。。。嗯,一切都好


之后,编写更多的单元测试。多次运行测试。在多个平台上。在晚上。周三。

如果你真的认为新结构更好,那么我会同意卢卡恩·格里戈尔的说法,但这不是唯一的选择。例如,您可以使用代理:

struct Base {
  virtual void doSomething() = 0;
};

void someFunction(Base &base)
{
  ...
  base.doSomething();
  ...
}

struct NewClass : Base {
  virtual void doSomething();
};

struct OldClassProxy : Base {
  OldClassProxy(OldClass &old) : old(old) { }

  virtual void doSomething()
  {
    old.doSomething();
  }

  OldClass &old;
};
现在,您可以将新函数用于旧类的实例,而无需修改旧类:

NewClass a;
OldClass b;
someFunction(a);
OldClassProxy b_proxy(b);
someFunction(b_proxy);
如果有很多地方需要代理,则可以编写重载:

void someFunction(OldClass &old_class)
{
  OldClassProxy proxy(old_class);
  someFunction(proxy);
}
这将允许您执行以下操作:

NewClass a;
OldClass b;
someFunction(a);
someFunction(b);

如果你真的认为新结构更好,那么我会同意Luchian Grigore的说法,但这不是唯一的选择。例如,您可以使用代理:

struct Base {
  virtual void doSomething() = 0;
};

void someFunction(Base &base)
{
  ...
  base.doSomething();
  ...
}

struct NewClass : Base {
  virtual void doSomething();
};

struct OldClassProxy : Base {
  OldClassProxy(OldClass &old) : old(old) { }

  virtual void doSomething()
  {
    old.doSomething();
  }

  OldClass &old;
};
现在,您可以将新函数用于旧类的实例,而无需修改旧类:

NewClass a;
OldClass b;
someFunction(a);
OldClassProxy b_proxy(b);
someFunction(b_proxy);
如果有很多地方需要代理,则可以编写重载:

void someFunction(OldClass &old_class)
{
  OldClassProxy proxy(old_class);
  someFunction(proxy);
}
这将允许您执行以下操作:

NewClass a;
OldClass b;
someFunction(a);
someFunction(b);

是否要重新编译使用该类的所有代码?如果是的话,很好。如果没有,则类的结构将发生更改,因此使用该类但未重新编译的代码将无法正常工作。是否有A的子类?您尚未说明为什么要进行这些更改。添加一个抽象基类意味着也会添加其他类,并且代码中会有一个重大更改,以使用该抽象类而不是当前正在使用的具体类。这是一次重大的重新设计。如果改变的原因只是一种整洁感,那就不要这样做。你知道,门面,包装,等等。不管怎样。@Vaughn Cato:如果良好的单元测试指的是任何测试,那么。。。你要重新编译所有使用这个类的代码吗?如果是的话,很好。如果没有,则类的结构将发生更改,因此使用该类但未重新编译的代码将无法正常工作。是否有A的子类?您尚未说明为什么要进行这些更改。添加抽象基类意味着
还将添加其他类,并且代码中将有一个重大更改,以使用该抽象类,而不是当前正在使用的具体类。这是一次重大的重新设计。如果改变的原因只是一种整洁感,那就不要这样做。你知道,门面,包装,等等。不管怎样。@Vaughn Cato:如果良好的单元测试指的是任何测试,那么。。。不