c++ - 如果我在我的 C++ 项目中使用 C 样式转换,是否值得重构为 C++ 转换?

标签 c++ refactoring casting

我在我的 15K LOC C++ 项目中使用 C 风格的转换,90% 的时间用于子类和基类之间的转换。

即使我读到使用它们很糟糕,而且它们可能导致严重的错误,因为它们不像 C++ 强制转换那样类型安全,我仍然感觉非常好并且很舒服使用它们。

到目前为止,我的项目中还没有遇到过一个错误,例如,由于意外输入错误的 C 样式转换导致 - 真的。

我没有使用它们的主要原因有两个:

  • 我对他们还不够了解
  • 我不喜欢它们的语法,它们更冗长,对我来说更难阅读

我的问题:

  • (为什么)我应该重构我的项目以使用 C++ 风格的强制转换吗?
  • 为什么我应该在我 future 的项目中使用 C++ 风格的转换?

我充分利用了 C++ 为我提供的所有其他优势,从 OOP 包括虚拟和抽象基类、命名空间、STL 等等,而不是新的类型转换语法。论点“那你为什么不直接使用 C 呢?”对我不起作用。

最佳答案

正如您所提到的,C++ 风格转换的主要优点是类型安全。 C++ 中的每个转换都处理一种特定类型的转换(或一系列相关转换),因此编译器可以检查您是否无意中进行了更多您想要的转换,或者从根本上不安全的一系列转换.

要考虑的一件事是,尽管您对使用 C 风格的强制转换感到自在很好,而且您没有犯任何错误也很好,但从事代码库工作的其他人可能不那么容易像你一样使用这些类型转换。使用强制转换操作符使代码更加自文档化。如果你在某处有 C 风格的类型转换,其他阅读代码的人可能无法立即推断出你在做什么。如果他们看到类似

T* ptr = (T*) var;

他们可能无法立即判断这是不是

  1. 从基类到派生类的强制转换或其他方式。
  2. var
  3. 中去除 const 特性的强制转换
  4. 从整数类型到指针的强制转换。

虽然他们可能可以从上下文中收集到这一点,但如果你使用像这样的类型转换会更明显地发生了什么

T* ptr = static_cast<T*>(var);

T* ptr = const_cast<T*>(var);

更喜欢 C++ 风格的强制转换运算符的另一个原因是它们使代码对更改更具弹性。例如,假设我有这个功能:

void DoSomething(Base* ptr) {
    Derived* derived = (Derived *) ptr;
    DoSomethingElse(derived);
}

现在,假设我意识到这个函数不应该对其参数进行任何更改,所以我决定将它标记为 const。例如:

void DoSomething(const Base* ptr) {
    Derived* derived = (Derived *) ptr;
    DoSomethingElse(derived);
}

但是现在我们遇到了一个问题——我的 C 风格转换过去只是进行向下转换,现在也剥离了 const 特性。这可能会导致一个简单的错误,即 DoSomethingElse 会改变我传入的指针,即使 DoSomething 方法本身 promise 不会这样做。如果我把这段代码写成

void DoSomething(Base* ptr) {
    Derived* derived = static_cast<Derived *>(ptr);
    DoSomethingElse(derived);
}

然后通过添加const来更改代码:

void DoSomething(const Base* ptr) {
    Derived* derived = static_cast<Derived *>(ptr);
    DoSomethingElse(derived);
}

现在我会收到一个编译器错误,告诉我我的旧转换已损坏,这可能导致我发现代码中存在逻辑错误(即 DoSomethingElse 改变了它的参数,所以我不能天真地使 ptr 成为指向 const 的指针。

简而言之,使用 C++ 强制转换运算符使代码更具可读性和可维护性。它使代码背后的逻辑更加明确。它通过让编译器在您制作错误时或稍后在您返回并更改旧代码时捕获错误,从而使代码不易出错。出于这些主要原因,我建议将来尝试使用 C++ 风格的强制转换运算符。

至于您是否应该返回并尝试用 C++ 样式的转换替换当前的 C 样式转换,这完全取决于您。作为一个练习,我建议这样做只是为了练习学习你正在使用什么类型的转换表。另外,您可能会在其中发现逻辑错误,这将使您的搜索值得您花时间!

关于c++ - 如果我在我的 C++ 项目中使用 C 样式转换,是否值得重构为 C++ 转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5046755/

相关文章:

c++ - 最基本的工作 vbo 示例

c++如何写一个构造函数?

c++ - 我违反了 D.R.Y.请帮帮我?

c# - 使用实体服务/存储库模式时,在模型中引用 System.Web.Security 是一种不好的做法吗?

java - 如何在 Eclipse 中将常量重构为枚举?

C++ 获取 "Segmentation Fault"Linux x64 的文件名和行号

c++ - 将与谓词匹配的相邻元组元素分组为子元组

c - 是否在 C 中将符号转换为无符号转换会更改位值

转换/不转换时 C# 无限值错误

c# - LINQ 查询抛出 InvalidCastException?