问题描述
我学习C ++已经有一段时间了,但是(这个问题一直困扰着我很多年).在学校里,我们的讲师喜欢将课堂变量声明为私有变量.为了访问它,我们必须声明一个访问器来访问它.
有时候,我们甚至不得不让不同的类成为朋友",以访问其元素.
我的问题是:为什么要这么麻烦?当我们可以通过使用公共事物来使我们的程序员生活变得更轻松时,所有私有和受保护的东西背后的真正原理是什么?
我在想,一旦代码被编译,最终用户甚至不会区分我们在后端编码中使用公共还是私有,那么为什么仍然需要正确地将其声明为私有,受保护...等?/p>
使您的代码更易于理解和维护.
当您将数据成员设为public
时,使用您的类的其他程序员自然会倾向于使用这些公共成员,而不是仅仅因为更容易而使用提供相似或相同信息的某些成员函数.您甚至可能会自己这样做.这是可以理解的-程序员天生就是懒人.
但是,假设您已经意识到,成员函数提供的信息将不再仅由一个成员变量生成.更糟糕的是,如果该成员变量在设计更改时过时了,该怎么办.更糟糕的是,如果没有删除成员变量本身,但是其语义发生了变化,那么该怎么办.
我们来看一个例子.假设您有一堂课,代表您要出售的物品:
class Gizmo
{
public:
std::string mSku;
};
就是这样,您所拥有的只是一个sku.假设mSku
的内容只是产品编号,例如"12345"
.
您完成代码,发布代码,生活就很美好.直到您的公司像亚马逊一样成功之前,现在您开始从多个供应商那里获得相同的产品.您决定最好的方法是编码 mSku
,以便它包含供应商信息以及产品编号.来自两个不同供应商的同一小部件可能具有非常不同的功能:S:12345
,Z:12345
.
编写的任何期望mSku
只是产品编号的代码现在都已损坏,所有这些都必须进行重构.在这个愚蠢的小例子中,这可能是一个问题.想象一下一个包含一百万行代码的代码库-一点也不罕见.您和您的所有同事可能已经忘记了所有使用mSku
的地方.没有任何代码将无法编译,因此编译器无济于事-但所有代码都被破坏了.这是一个很大的问题.
如果您一开始完全不依赖mSku
,但是提供了一个成员函数,该成员函数可以返回产品编号,那么从一开始就更好.像这样:
class Sku
{
public:
std::string ProductNumber() const;
private:
std::string mSku;
};
现在您可以随意更改mSku
的语义.只要您重构ProductNumber()
的操作以返回产品编号,那么所有这100万行代码仍将编译并且仍然是正确的.
实际上,我通常会更进一步.我通常会在class
private
中制作所有内容,直到有特殊原因需要制作其他内容为止.即使那样,除非我确实需要将其设置为public
,否则我只会将其设置为protected
.
在大型代码库中,即使仅由一个人维护,从一开始就通过制作很多private
东西,实际上可以使您的生活从长远来看./p>
I've learn C++ for some time, however there is always this question which puzzles me (for years). In school, our lecturers like to declare class variables as private. In order to access it, we have to declare an accessor to access it.
Sometimes we even have to make the different classes become "friends" into order to access its elements.
My question is: Why make it so troublesome? What is the true rationale behind all the private and protected stuff when we can just make our life as a programmer easier by using public for everything?
I was thinking, once the code gets compiled, the end user will not even differentiate whether we use public or private in the back end coding, so why still need to declare it properly as private, protected...etc ?
To make your code easier to understand and maintain.
When you make a data member public
, other programmers who use your class will naturally tend to use these public members rather than some member function that provides similar or the same information simply because it's easier. You might even tend to do this yourself. That's understandable -- programmers are inherently lazy beasts.
But suppose you realize somewhere down the line that the information that member function provides can no longer be generated from just that one member variable. Worse, what if that member variable becomes obsolete in the face of a design change. Worse still, what if the member variable itself isn't removed, but the semantics of it change.
Let;s consider an example. Say you have a class which represents items you have for sale:
class Gizmo
{
public:
std::string mSku;
};
That's it, all you have is a sku. Suppose the contents of mSku
are simply the product number, something like "12345"
.
You finish your code, ship it, and life's great. Until your company becomes as successful as Amazon, and now you start getting the same product from multiple vendors. You decide that the best thing to do is to encode the mSku
so that it contains vendor information along with the produce number. The same widget from two different vendors might have very different skus: S:12345
, Z:12345
.
Any code that was written that expects mSku
to be just a product number is now broken, and it will all have to be re-factored. In this silly little example it could be a problem. Imagine a codebase of 1 million lines of code -- not uncommon at all. You and all your coworkers have probably forgotten all about all the places where mSku
is being used. None of the code will fail to compile, so the compiler's no help -- but all of that code is broken. This is a huge problem.
It would have been better at the outset if you hadn't relied on mSku
at all, but provided a member function which was contracted to return the product number. Something like:
class Sku
{
public:
std::string ProductNumber() const;
private:
std::string mSku;
};
Now you can change the semantics of mSku
all you want. So long as you refactor what ProductNumber()
does to return the product number, all those 1 million lines of code will still compile and still be correct.
In fact, I generally take this one step further. I will generally make everything in a class
private
until there is a specific reason to make it something else. Even then, I'll only make it protected
unless I actually need it to be public
.
In a large codebase, even if it's only maintained by one person, you actually make your life easier in the long run by making a lot of this stuff private
from the very start.
这篇关于为什么将班级成员设为私人?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!