纯抽象类与其实现的数据隔离与纯抽象类的真正含义? [英] Data isolation between pure abstract class against its implmentation and the true meaning of pure abstract class?

查看:34
本文介绍了纯抽象类与其实现的数据隔离与纯抽象类的真正含义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Bjarne Stroustrup 的The C++ Programming Language"一书中,它指出,在很多情况下,从类层次结构中的超类派生的类可以访问超类的数据.这本书认为这是一个问题,因为两个相关但不同的数据集之间的共享是在自找麻烦.迟早有人会让它们不同步.此外,经验表明,新手程序员倾向于以不必要的方式处理受保护的数据并导致维护问题".这里的问题是,从祖先类访问私有数据怎么会自找麻烦?听起来从父类继承资产是一件坏事.

In Bjarne Stroustrup's book "The C++ Programming Language", it is stated that a derived class from a super class in a class hierarchy, in many case, gets access to the data of the super class. The book suggests this is a problem, because the sharing between "two related, but different, sets of data is asking for trouble. Sooner or later someone will get them out of sync. Also, experience shows that novice programmers tend to mess with protected data in ways that are unnecessary and that cause maintenance problems". The question here is, how can having access to private data from the ancestor class is asking for trouble? It sounds like having inherited assets from your parent is a bad deal.

因此,纯抽象类机制允许抽象类与其实现之间的分离.注意实现中包含数据成员,因为如果数据成员定义在抽象类中,抽象类包含实现细节(定义的成员),因此抽象和实现之间没有很好的解耦.为什么需要这样的分离?如此处所述,原因之一是"一种在类设计者和该类的用户之间强制签订契约的方法.这个类的用户必须声明一个匹配的成员函数才能编译该类."另一个重要原因,如本书,是为了防止实施中的变化.拥有抽象类层次结构,您可以防止需要编译整个类层次结构的更改.

As a consequence, the pure abstract class mechanism allows the separation between the abstract class and its implementation. Note that the implementation includes data members, because if the data members are defined in an abstract class, the abstract class contains implementation details (the defined members), thus it is not well decoupled between abstraction and the implementation. Why is such separation needed? One of the reason, as stated in here, is "a way of forcing a contract between the class designer and the users of that class. The users of this class must declare a matching member function for the class to compile." Another important reason, as stated in the book, is to protect against changes from the implementation. Having an abstract class hierarchy, you can protect against the changes which requires compilation of an entire class hierarchy.

举个例子,如果你有一个普通的类,这个类包含10个数据成员和20个成员函数,并且被根类下面几层的十几个类继承.对根类的成员函数(函数签名保持不变)的实现进行一些更改,您必须重新编译整个类层次结构以应用其终端类的更改,否则程序会中断.对于抽象类层次结构,除非函数签名发生变化,否则如果终端类的实现发生变化,则只需重新编译该终端类.因此,大部分代码都受到最大程度的保护.我的理解是否正确?

For example, if you have a normal class, and the class contains 10 data members and 20 member functions, and is inherited by a dozen of classes with several layers below the root class. A few changes to the implementation of member functions (function signature remains unchanged) of the root class, and you have to recompile the entire class hierarchy to apply changes its terminal classes, otherwise the program breaks. With abstract class hierarchy, unless the function signature is changed, if an implementation of a terminal class changes, only that terminal class needs to be recompiled. Therefore, most of the code are protected to the maximum. Is my understanding correct?

我认为他的示例(Ival_box 示例)与桥设计模式相结合尝试并且非常强大,因为桥模式完全离开了抽象树,并且有另一个用于实现的类层次结构.纯抽象类可以认为相当于Java中的Interface,只不过Java中的解释通常是抽象类可以被继承一次,而接口允许多次继承,因此具有共享性行为封装在多个类之间的共享接口中.我认为,这个答案在这种情况下是无效的,因为 C++ 允许多重继承.

I think his example (the Ival_box example) in combination with the Bridge Design Pattern tries, and is powerful, since Bridge Pattern leaves the abstract tree completely, and have another class hierarchy for implementation. Pure abstract class can be consider equivalent to Interface in Java, except in Java the explanation usually is the abstract class can be inherited once, while interface allow multiple inheritances, thus having shared behaviors encapsulated in a shared interface between multiple classes. That answer, I think, is not valid in this context, since C++ allows multiple inheritance.

最后一个问题是,派生类是如何编译并存在于二进制映像中的? 编译器是否将继承的信息填充到派生类中,然后认为它是一个孤立类然后编译?(类似于预处理)

The last question is, how is a derived class compiled and exist in the binary image? Does the compiler fill the inherited information into the derived class, considered it to be an isolated class afterward and then compiled? (Similar to preprocessing)

tl;dr:

从祖先类访问私有数据怎么会自找麻烦?

纯抽象类(Java 中的接口)是否是一种保护源代码免受更改的方法,抽象树和实现树是分离的?

抽象类/超类是如何用C++编译的?是不是通过填写超类的信息将派生类变成单个类,然后编译

推荐答案

元注:您的问题可以作为多个单独的问题提出.

Meta-note: Your questions could have been asked as multiple, separate questions.

从祖先类访问私有数据怎么会自找麻烦?

how can having access to private data from the ancestor class is asking for trouble?

非正交性.当祖先类的受保护部分更改时,所有派生类也必须更改.这很容易出错,因为更改祖先的程序员可能在他的心理范围内没有派生类.

Non-orthogonality. When the protected part of the ancestor class is changed, all derived classes have to be changed, too. This is error-prone, because the programmer changing the ancestor might not have the derived classes in his mental scope.

对于抽象类层次结构,除非函数签名发生变化,否则如果终端类的实现发生变化,则只需重新编译该终端类.

With abstract class hierarchy, unless the function signature is changed, if an implementation of a terminal class changes, only that terminal class needs to be recompiled.

技术上是正确的,但您没有抓住要点.重新编译不是很好,但也不是非常昂贵,因为计算机会这样做.真正的成本是由非正交性引起的人工工作.当一个类有一个公共或受保护的数据成员时,人们就会使用它,而当它发生变化时,事情就会中断,必须加以修复.

Technically correct, but you are missing the main point. Recompilation is not nice, but also not terribly costly, because computers do it. The real cost is human work induced by non-orthogonality. When a class has a public or protected data member, people are going to use it, and when it changes, things break and have to be fixed.

顺便说一句,被十几个类继承,在根类下面有几层"通常是糟糕设计的标志.保持继承层次结构简洁明了.优先使用成员而不是基类:当您决定在类 Bar 中使用类 Foo 的功能时,没有令人信服的理由让 Bar 继承 Foo,而是使用类型 Foo 的成员.

BTW, "is inherited by a dozen of classes with several layers below the root class" is usually a sign of bad design. Keep inheritance hierarchies flat and concise. Prefer members over base classes: When you decide to use functionality of a class Foo in a class Bar, and there is no compelling reason to let Bar inherit Foo, rather use a member of type Foo.

我认为这个答案在这种情况下是无效的,因为 C++ 允许多重继承.

That answer, I think, is not valid in this context, since C++ allows multiple inheritance.

在C++中,接口和类之间的区别没有具体化(变成一个东西),但仍然使用.在很多情况下构建接口是非常有用的,例如由抽象虚函数组成的类,因为它们避免了非常可怕的多重继承的许多麻烦.

In C++, the distinction between interfaces and classes is not reified (made into a thing), but still used. It is very useful in many cases to build interfaces, e.g classes consisting of abstract virtual functions, because they avoid many of the troubles of the much-dreaded multiple inheritance.

派生类是如何编译并存在于二进制映像中的?

how is a derived class compiled and exist in the binary image?

这是特定于编译器的.暂时不要担心 - 首先了解语言,然后是实现.

This is compiler-specific. Don't worry about it just yet - first understand the language, then it's implementation.

这篇关于纯抽象类与其实现的数据隔离与纯抽象类的真正含义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆