c++ - C++ 中的名称隐藏静态成员函数 : good practice?

标签 c++ inheritance

在我作为一名 C++ 程序员期间,我通常认为应该避免名称隐藏,因为它会导致困惑。例如,如果您有一个带有函数 f() 的基类和一个带有函数 f() 的派生类,并且 f() 不是虚拟的,则调用者可能会意外调用错误的 f()。

但是,我在阅读 Herb Sutter 的《Exceptional C++》一书中遇到了一个示例,其中似乎鼓励隐藏名称。为了制作一个不区分大小写的字符串,他建议我们制作 std::basic_string<> 的不区分大小写的版本。通过创建 char_traits继承自 char_traits<char> 的类(这是一个非多态静态类)像这样:

struct ci_char_traits : public char_traits<char>
{
  static bool eq( char c1, char c2 ) { /*...*/ }
  static bool lt( char c1, char c2 ) { /*...*/ }
  static int compare( const char* s1,
                      const char* s2,
                      size_t n)       { /*...*/ }
  static const char*
  find( const char* s, int n, char a ) { /*...*/ }
}

(我省略了函数定义以使其更简洁)。本质上,我们继承了char_traits<char>的所有功能。 ,并且我们隐藏了要修改的内容以使其不区分大小写。然后,您定义不区分大小写的字符串,如下所示:

typedef basic_string<char, ci_char_traits> ci_string;

现在我确实认为这是一个非常巧妙的技巧!但我想知道这种事情是否被认为是“良好做法”,因为隐藏姓名通常会引起人们的不满。也许名称隐藏静态成员函数比其他类型的函数更容易被接受?

最佳答案

这里的区别在于,traits 类不是多态的,因此永远不会对使用哪个接口(interface)产生任何混淆。

ci_char_traits当然可以通过私有(private)继承、封装或简单地遵循 std::char_traits<> 来实现。所有这些方法都需要更多的维护。

更新:

评论中有一些关于模板是否多态的讨论。我会详细说明。

构造std::basic_string<char, ci_char_traits>导致模板的模板扩展std::basic_string<class CharT, class Traits, class Allocator> 。在此扩展期间,进行了以下类型替换:

  • CharT替换为 char
  • Traits替换为 ci_char_traits
  • Allocator替换为 std::allocator<char>

因此,编译器生成的类是:

std::basic_string<char, ci_char_traits, std::allocator<char>>

这不是多态类。

此类将有一个名为 std::basic_string<char, ci_char_traits, std::allocator<char>>::traits_type 的成员 typedef ,这无疑是 ci_char_traits 类型.

因此,此模板扩展将产生一个使用非多态类 ci_char_traits 的非多态类。确定基于字符的操作(例如比较)的行为。

eq 的哪个过载和lt将由类 std::basic_string<char, ci_char_traits, std::allocator<char>> 中的代码调用是精确定义的,这就是为什么在这种情况下,重载这些静态成员函数并不是一个坏习惯。

关于c++ - C++ 中的名称隐藏静态成员函数 : good practice?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47601774/

相关文章:

c++ - 使用嵌套映射的可变模板参数推断

c++ - 使用 MPI_Scatter 时出现段错误

C++ 类后跟模板关键字

c++ - 如何在派生类中初始化静态成员?

具有空派生类对象的 C++ 继承大小

java - 父类(super class)变量的子类引用?

c++ - 在 C#/C++ 中创建数据包过滤器?

c++ - 计算机视觉 : Image Comparison and Counting?

CSS 继承 : How to override inherited values

c++ - 为一个模板类提供多个模型以供选择