C++中的抽象类机制有什么特别之处?

发布于 2024-10-04 10:18:15 字数 137 浏览 10 评论 0原文

我有一个问题困扰了我几天。

抽象类是一种特殊类型的类,我们无法实例化,对吗? (这是通过给至少一个方法声明赋予“= 0”来表示/指定的,这看起来像是事后的想法)。

抽象类机制给 C++ 带来了哪些“普通”基类无法实现的额外好处?

I have question that bothers me for few days.

Abstract class is a special type of class that we cannot instantiate, right?. (Which is denoted/specified by giving a "= 0" to at least one method declaration, which looks like an afterthought).

What are the extra benefits that the abstract class mechanism brings to C++, that a 'normal' base class cannot achieve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

划一舟意中人 2024-10-11 10:18:15

根据 wikibooks 关于抽象类的部分

这是一种在类设计者和该类的用户之间强制签订契约的方法。如果我们希望从抽象类创建一个具体类(可以实例化的类),我们必须为基类的每个抽象成员函数声明并定义一个匹配的成员函数。

如前所述,它是一种定义派生类必须遵守的接口的方法。他们的 Vehicle 抽象类示例非常恰当:在现实生活中,您永远不会只有一辆 Vehicle,您会拥有一辆福特探险者或丰田普锐斯,但是它们都符合(为了论证)Vehicle 可能定义的一组基本功能。但是,您不能直接前往 Vehicle 经销店并将 Vehicle 开出停车场。因此,您永远不会希望能够在您真正需要专门的派生对象的情况下构造和使用基本 Vehicle 对象。

According to the wikibooks section on abstract classes:

It's a way of forcing a contract between the class designer and the users of that class. If we wish to create a concrete class (a class that can be instantiated) from an abstract class we must declare and define a matching member function for each abstract member function of the base class.

As mentioned, it's a way of defining an interface to which derived classes must adhere. Their example of the Vehicle abstract class is very apropos: you'd never have just a Vehicle in real life, you'd have a Ford Explorer or a Toyota Prius, but those both conform to (for the sake of argument) a base set of functionality that being a Vehicle might define. But, you can't just go to the Vehicle dealership and drive a Vehicle off the lot. Thus, you'd never want to be able to construct and use a base Vehicle object where you'd really want a specialized, derived object.

止于盛夏 2024-10-11 10:18:15

这提供了在 C++ 中定义接口而不需要任何默认实现的最佳方法。

C++ 没有 C# 的接口 概念。

This offers the best way in C++ to define an interface without any default implementation.

C++ does not have C#'s interface concept.

我做我的改变 2024-10-11 10:18:15

它相当于 Java 变成的“接口”。基本上,它意味着类本身不可用 - 您需要重写所有纯方法。

一个例子是 MFC 的 CView 类,它有一个纯 OnDraw 方法 - 基本的 CView 不执行任何操作,因此毫无用处。您必须重写 OnDraw。

(顺便说一句 - 仍然可以为纯方法提供实现,并且子类实现可以回退到它,但它们仍然必须提供自己的覆盖。)

It's the equivalent of what Java turned into "interfaces". Basically, it implies that the class itself is not usable - you need to override all pure methods.

An example is MFC's CView class which has a pure OnDraw method - the basic CView doesn't do anything and is as such useless. You have to override OnDraw.

(Btw - it is still possible to provide an implementation for a pure method, and subclassed implementations can fall back to it, but they still have to provide their own override.)

玩心态 2024-10-11 10:18:15

它们在类层次结构设计中用作基类。
抽象类用于为所有派生类定义干净的接口。
在设计阶段,抽象类根据规范定义一个接口,派生类相应地实现所需的功能。
此外,使用抽象类而不是“普通”类有助于将实现细节与接口分离。
具体类实现接口,但抽象类定义接口。您可以在设计中使用具体类作为基类,但抽象类不能直接在代码中使用,也不能实例化。它们作为原型。
通过使用您所说的“普通”类,您必须为所有方法定义一个实现。

They are used as a base class in a class hierarchy design.
Abstract classes are used to define a clean interface for all derived classes.
At design stage, abstract classes define an interface, per specification and derived classes implement the desired functionality accordingly.
Also using abstract classes instead of "normal" classes helps separating the implementation details from the interface.
A concrete class implements an interface, but the abstract class defines it. You could use a concrete class as a base class in your design but abstract classes are not meant to be used directly in code and can not be instantiated. They serve as prototype.
By using the "normal" class as you say, you have to define an implementation for all methods.

划一舟意中人 2024-10-11 10:18:15

不要在班级层面上考虑。

查看该方法,并考虑在默认情况下它应该做什么:

virtual std::string getName() const = 0;

该方法的正确实现是什么?我想不到。

通过将其标记为“纯虚拟”,您可以确保如果用户获得从您的接口派生的类的实例,则此方法将具有合理的行为。

唯一的其他方法是使用 throw NotImplemented("getName"); 主体,但是您会在运行时而不是在编译时发现问题,这不太好: )

Don't think of it at the class level.

Look at the method, and think of what it should do in the default case:

virtual std::string getName() const = 0;

What would be a right implementation for this method ? There is none than I can think of.

By marking it "pure virtual", you ensure that if the user ever get an instance of a class derived from your interface, then this method will have a sensible behavior.

The only other way to do this would be a throw NotImplemented("getName"); body, but then you'd discover the issue at runtime, not at compile-time, which is not as nice :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文