距离上次使用c++已经很久了,从java和python回来,想请教一下关于c++的良好实践:
我想保留关于一些非常简单的对象的语义代码,假设我们有对象 Tag 和 File,它们都是 std::string 和一个类 TagManager,它包含几个使用 Tags 和 Files 的函数。
我的问题是,是创建一个自定义类型来表示这些琐碎的对象还是直接使用它们更好?
更具体地说,我可以为函数定义其中一个:
TagIterable myFunction(Tag tag, File file);
std::vector<Tag> myFunction(Tag tag, File file);
std::vector<std::string> myFunction(std::string tag, std::string file);
我更喜欢第一种解决方案,因为我喜欢保留语义代码,另一方面这样做需要用户检查这些类型是什么,因此降低了使用的简单性。
我还阅读了另一个问题 (Thou shalt not inherit from std::vector)“不要为了让某些东西看起来更好而产生新实体。”
那么在这种情况下你会怎么做? C++哲学建议做什么?
最佳答案
我通常使用typedef
在这种情况下:
- 尽管
typedef
不要引入新的类型或讨厌的std::vector<>
衍生物别名本身,对于那些使用您的代码的人来说,别名可能仍然是令人讨厌的间接访问。 - 另一方面,它们可以很好地公开和记录(提供示例),以便每个人从一开始就使用它们。
- 它们有助于避免构建破坏者,以防需要更改类型(前提是在您的特定情况下未使用或在替换中提供特殊
std::string
功能)。 - 因此,如果需要,一个
typedef
稍后可以更改为具有额外属性和功能的新类的别名,或者只是为了类型安全。 - 它们允许轻松跟踪使用位置,以及在大多数 IDE 中进行重构。
namespace mylib
{
typedef std::string Tag; //perhaps 'TagType' or 'tag_type', to follow the naming
//conventions of the standard library, e.g.
//std::vector::value_type
typedef std::string File;//Same as above, 'FileName' might be more appropriate
typedef std::vector<Tag> TagIterable;
//Could be named 'TagContainer',
//`TagVector` or `TagSet` when using std::set,
//to match the terminology of C++
TagIterable myFunction(const Tag& tag,const File& file);
//One may use references to const here,
//to explicitly avoid unnecessary copies
};
关于用于语义的 C++ 包装类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20174180/