您的位置:首页 > 编程语言 > C语言/C++

Effective C++条款22解读: 将成员变量生命为private

2015-06-21 16:07 393 查看
       我们先来看一个简单的程序:

#include <iostream>
#include <string>
using namespace std;

// 类的提供者
class Programmer
{
public:
string name;
string address;

// 如下的两个const不可少
void set(const string &tmpName, const string &tmpAddress)
{
name = tmpName;
address = tmpAddress;
}
};

// 类的使用者
int main()
{
Programmer pro;
pro.name = "eric";
pro.address = "China";

return 0;
}
      当然, 这个程序运行肯定是没有问题的, 但某一天, 类的提供者觉得address这个名称太长太恶心, 想换成addr, 于是就成了这样的程序:

#include <iostream>
#include <string>
using namespace std;

// 类的提供者
class Programmer
{
public:
string name;
string addr;

// 如下的两个const不可少
void set(const string &tmpName, const string &tmpAddr)
{
name = tmpName;
addr = tmpAddr;
}
};

// 类的使用者
int main()
{
Programmer pro;
pro.name = "eric";
pro.address = "China";

return 0;
}
       显然, 类的使用者没法觉察到改变, 程序编译有错。 即使类的提供者告诉类的使用者要改变address字段, 那你想想, 类的使用者该有多恼火啊, 如果程序非常大, 那就更加糟糕了。

       为什么会产生这样的尴尬局面呢? 原来, 类的使用者直接操作了成员变量, 这不是类的使用者的错, 而是类的提供者的错, 所以, 在提供类的时候, 不要把成员变量定义为public, 我们来改一下第一个程序:

#include <iostream>
#include <string>
using namespace std;

// 类的提供者
class Programmer
{
private:
string name;
string address;

public:
// 如下的两个const不可少
void set(const string &tmpName, const string &tmpAddress)
{
name = tmpName;
address = tmpAddress;
}
};

// 类的使用者
int main()
{
Programmer pro;
pro.set("eric", "China");

return 0;
}
      此时, 如果类的提供者再改变, 就不要通知类的使用者了, 而且类的使用者也确实不需要做出任何改变, 我们看来看类的提供者将address改为addr后的情况:

#include <iostream>
#include <string>
using namespace std;

// 类的提供者
class Programmer
{
private:
string name;
string addr;

public:
// 如下的两个const不可少
void set(const string &tmpName, const string &tmpAddr)
{
name = tmpName;
addr = tmpAddr;
}
};

// 类的使用者
int main()
{
Programmer pro;
pro.set("eric", "China");

return 0;
}
       编译通过, 程序OK, 类的使用者完全不知道有变更这回事.  看看, 责任清晰, 多好啊。

       上面仅仅从程序可扩展性的角度考虑用private封装数据成员, 那还有没有别的原因呢? 肯定有, 你想想, 如果类的使用者能直接操作数据成员, 那还得了。 所以, 从安全性的角度来考虑, 也该用private.

        Scott Meyers也说了, 用protected会存在类似的问题。 所以, 在Effective C++中, 作者强调:将成员变量生命为private(而不是public或者protected, 实际上, protected并不会比public号多少)

        

        其实, 将成员变量生命为private, 这个条款是很好理解的, 最近买了一个iphone 6 plus, 果果手机把内部封锁得这么严, 其实与我们把类封锁得严严实实的, 是同一个道理。 让用户接触该接触的, 接触不到不该接触的。

        


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: