C++核心准则C.9:最小限度暴露成员

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++核心准则C.9:最小限度暴露成员相关的知识,希望对你有一定的参考价值。


C.9: Minimize exposure of members

C.9:最小限度暴露成员

Reason(原因)

Encapsulation. Information hiding. Minimize the chance of unintended access. This simplifies maintenance.

封装性。信息隐藏。将非故意访问的可能性降至最低。简化维护。

译者注:这是封装最直接的好处。

Example(示例)


 


 

template<typename T, typename U>
struct pair
T a;
U b;
// ...
;

 

Whatever we do in the ​​//​​​-part, an arbitrary user of a ​​pair​​​ can arbitrarily and independently change its ​​a​​​ and ​​b​​​. In a large code base, we cannot easily find which code does what to the members of ​​pair​​​. This may be exactly what we want, but if we want to enforce a relation among members, we need to make them ​​private​​and enforce that relation (invariant) through constructors and member functions. For example:

无论我们在注释的位置做什么,pair的任何用户都可以随意、独立的修改数据成员a和b。在大规模代码中,我们无法简单地发现是哪段代码对pair的成员做了什么。如果这就是我们想要的当然没问题,但是如果我们想要加强成员间联系,就需要将它们变更为私有成员并通过构造函数和成员函数强化这种联系(不变式)。例如:


 



class Distance 
public:
// ...
double meters() const return magnitude*unit;
void set_unit(double u)

// ... check that u is a factor of 10 ...
// ... change magnitude appropriately ...
unit = u;

// ...
private:
double magnitude;
double unit; // 1 is meters, 1000 is kilometers, 0.001 is millimeters, etc.
;

Note(注意)

If the set of direct users of a set of variables cannot be easily determined, the type or usage of that set cannot be (easily) changed/improved. For ​​public​​​ and ​​protected​​ data, thats usually the case.

如果无法简单地决定一组变量的直接用户,这组变量的类型和用法就无法(简单地)变更和改善。公有或保护成员,基本上属于这种情况。

Example(示例)

A class can provide two interfaces to its users. One for derived classes (​​protected​​​) and one for general users (​​public​​). For example, a derived class might be allowed to skip a run-time check because it has already guaranteed correctness:

一个类可以向用户提供两类接口。一类面向派生类(保护成员),一个面向普通用户(公有成员)。例如,由于已经保证了正确性,某个派生类可能会允许省略某项运行时检查。


 



class Foo 
public:
int bar(int x) check(x); return do_bar(x);
// ...
protected:
int do_bar(int x); // do some operation on the data
// ...
private:
// ... data ...
;
class Dir : public Foo
//...
int mem(int x, int y)

/* ... do something ... */
return do_bar(x + y); // OK: derived class can bypass check

;
void user(Foo& x)

int r1 = x.bar(1); // OK, will check
int r2 = x.do_bar(2); // error: would bypass check
// ...

Note(注意)

​protected​​ data is a bad idea.

保护型数据是个坏主意。

Note(注意)

Prefer the order ​​public​​​ members before ​​protected​​​ members before ​​private​​ members see.

较好的顺序是公有成员在保护成员之前,保护成员又在私有成员之前。

译者注:还有一个类似的规则是:如果成员之间有调用关系,那么调用者在前,被调用者在后。

Enforcement(实施建议)

  • Flag protected data.
    在发现保护型数据时进行提示。
  • Flag mixtures of ​​public​​ and private ​​data​

       在发现公有和私有数据混杂在一起时进行提示。

 


以上是关于C++核心准则C.9:最小限度暴露成员的主要内容,如果未能解决你的问题,请参考以下文章

C++核心准则F.54:不要隐式捕捉this指针

C++核心准则边译边学-F.17 输入/输出参数传递非常量引用

C++ 通过分配其他构造函数初始化的类成员来初始化类成员是一个坏主意吗?

C++核心准则T.22:为概念定义公理

C++核心准则F.55 不要使用可变参数

C++核心准则边译边学-文档结构