我想问一下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;
};
哪个版本是最佳做法?
答案 0 :(得分:12)
这取决于您在哪里使用类型别名。我建议你
编译器将只强制使用别名范围太窄(例如,您使用在该类之外的类的私有部分中定义的类型别名),并且如果选择了不必要的允许范围(例如,公开声明别名,但只能在类实现中使用它)。因此,力求选择尽可能小的范围,这与隐藏实施细节是一致的。
作为旁注,您可能需要考虑使用using StrIntPair = std::pair<std::string, int>;
声明类型别名,请参阅有效现代C ++中的项目9。不过,这对上面没有影响。
答案 1 :(得分:1)
问题在于这些名称的逻辑名称空间。对于StrIntPair
,StrIntPairVec
和MyData
这样的抽象命名,没有答案。当事物有意义时,答案就来了。
让我们采用完全相同的数据结构,但将它们命名为NickAndId
,Friends
和Player
。
现在,是否将NickAndId
放在Player
中的问题是关于它是否特定于玩家。其他实体,例如NonPlayerCharacter
或Creature
是否也可以将昵称和ID表示为同一对?可能吧。那应该在外面。
对于Friends
,应该问相同的问题。 NonPlayerCharacter
和Creature
可能有昵称和ID,但没有朋友吗?然后将类型放在Player
内作为Player::Friends
是有意义的。
最后,设为私有的类型仅用于实现详细信息。当名称在类内部使用的算法中很有意义,但不需要外部名称,或者甚至更糟,令人困惑时,应使用该名称。例如,NonPlayerCharacter
可以对某些状态作出反应,使其状态值也属于该NPC。将其保存在排序的向量Reactions
中在类内部非常有意义。从外部访问ReplicaInState
和Reactions
可能会造成混乱。