C ++中正确的typedef位置

时间:2018-08-29 08:05:20

标签: c++ typedef

我想问一下typedef在C ++中的正确​​位置。

版本1:类外的typedef

typedef std::pair<std::string, int> StrIntPair;
typedef std::vector<StrIntPair> StrIntPairVec;

class MyData
{
public:
    MyData(){};
    ~MyData(){};
private:
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

版本2:在类public中的typedef

class MyData
{
public:
    MyData(){};
    ~MyData(){};
    typedef std::pair<std::string, int> StrIntPair;
    typedef std::vector<StrIntPair> StrIntPairVec;
private:
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

版本3:私有类内的typedef

class MyData
{
public:
    MyData(){};
    ~MyData(){};
private:
    typedef std::pair<std::string, int> StrIntPair;
    typedef std::vector<StrIntPair> StrIntPairVec;
    void addInfo(const StrIntPair &info)
    {
        infoVec.push_back(info);
    }
    StrIntPair info;
    StrIntPairVec infoVec;
};

哪个版本是最佳做法?

2 个答案:

答案 0 :(得分:12)

这取决于您在哪里使用类型别名。我建议你

  • 如果您在类和/或函数中使用它们,则将它们放在类之外,并且别名的含义并不只与类相关。
  • 如果类外部的客户端代码需要访问它们(例如,初始化对象或存储成员函数的别名返回值),但将它们定义为公共类类型别名,但别名与该类相关。别名然后成为类接口的一部分。
  • 当您在类中专门使用它们时,将它们定义为私有类类型别名。跨成员函数传递时总是烦人的一些实用程序数据结构。

编译器将只强制使用别名范围太窄(例如,您使用在该类之外的类的私有部分中定义的类型别名),并且如果选择了不必要的允许范围(例如,公开声明别名,但只能在类实现中使用它)。因此,力求选择尽可能小的范围,这与隐藏实施细节是一致的。

作为旁注,您可能需要考虑使用using StrIntPair = std::pair<std::string, int>;声明类型别名,请参阅有效现代C ++中的项目9。不过,这对上面没有影响。

答案 1 :(得分:1)

问题在于这些名称的逻辑名称空间。对于StrIntPairStrIntPairVecMyData这样的抽象命名,没有答案。当事物有意义时,答案就来了。

让我们采用完全相同的数据结构,但将它们命名为NickAndIdFriendsPlayer

现在,是否将NickAndId放在Player中的问题是关于它是否特定于玩家。其他实体,例如NonPlayerCharacterCreature是否也可以将昵称和ID表示为同一对?可能吧。那应该在外面。

对于Friends,应该问相同的问题。 NonPlayerCharacterCreature可能有昵称和ID,但没有朋友吗?然后将类型放在Player内作为Player::Friends是有意义的。

最后,设为私有的类型仅用于实现详细信息。当名称在类内部使用的算法中很有意义,但不需要外部名称,或者甚至更糟,令人困惑时,应使用该名称。例如,NonPlayerCharacter可以对某些状态作出反应,使其状态值也属于该NPC。将其保存在排序的向量Reactions中在类内部非常有意义。从外部访问ReplicaInStateReactions可能会造成混乱。