C++ FAQ Lite[22]--继承(抽象基类)(更新)

[22] 继承 — 抽象基类(ABCs)
(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档


FAQs in section [22]:


[22.1] 将接口和实现分离的作用是什么?

接口是公司最有价值的资源。设计接口比用一堆类来实现这个接口更费时间。而且接口需要更昂贵的人力的时间。

既然接口如此有价值,它们应该被保护,以免因为数据结构和其他实现的改变而被破坏。因此,应该将接口和实现分离。

TopBottomPrevious sectionNext section ]


[22.2] 在C++中如何分离接口和实现(就象 Modula-2)?

使用ABC。(译注:即抽象基类 abstract base class)

TopBottomPrevious sectionNext section ]


[22.3] 什么是 ABC? UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes .]

抽象基类(abstract base class)。

在设计层次,抽象基类(ABC)对应于抽象概念。如果你问一个机修工他是否修理交通工具,他可能想知道你所说的是哪种交通工具。他不修理航天飞机、远洋轮、自行车或核潜艇。问题在于“交通工具”是一个抽象概念(例如,除非你知道你要建造哪种交通工具,否则你无法建造一个“交通工具”)。在C++中,Vehicle(交通工具)类是一个ABC,而Bicycle(自行车),SpaceShuttle(航天飞机)等则是派生类(OceanLiner(远洋轮)是一种Vehicle)。在真实世界的OO中,ABC无处不在。

在程序语言层次上,抽象基类(ABC)是有一个或多个纯虚成员函数的类。无法建立抽象基类的对象(实例)。

TopBottomPrevious sectionNext section ]


[22.4] 什么是“纯虚”成员函数? UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes .]

将普通类变成抽象基类(也就是ABC)的成员函数。通常只在派生类中实现它。

某些成员函数只在概念中存在,而没有合理的定义。例如,假设我让你在坐标(x,y)处画一个图形,大小为 7。你会问我:“我应该画哪种图形?”(圆,矩形,六边形等,画法都不同)。在C++中,我们必须指出 draw() 成员函数的实在物(由此用户才能在有一个Shape*或者 Shape& 的时候调用它),但我们认识到,在逻辑上,它只能在子类中被定义:

 class Shape {
 public:
   virtual void draw() const = 0;  
// = 0 表示它是 "纯虚" 的
   
// ...
 };

这个纯虚函数使 Shape 成为了ABC(抽象基类)。如果你愿意,你可以将“= 0;”语法看作为代码位于NULL指针处。因此 Shape 向它的用户承诺了一个服务,然而 Shape 无法提供任何代码来实现这个承诺。这样做使得即使基类没有足够的信息来实际定义成员函数时,也强制了任何由 Shape 派生的具体类的对象须给出成员函数。

注意,为纯虚函数提供一个实现是可能的,但是这样通常会使初学者糊涂,并且最好避免这样,直到熟练之后。

TopBottomPrevious sectionNext section ]


[22.5] 如何为包含指向(抽象)基类的指针的类定义拷贝构造函数或赋值操作符?

如果类拥有被(抽象)基类指针指向的对象,则在(抽象)基类中使用虚构造函数用法。就如同一般用法一样,在基类中声明一个纯虚方法 clone() :

 

 class Shape {
 public:
   
// ...
   virtual Shape* clone() const = 0;   
// 虚拟(拷贝)构造函数
   
// ...
 };

然后在每个派生类中实现 clone()方法:

 class Circle : public Shape {
 public:
   
// ...
   virtual Shape* clone() const { return new Circle(*this); }
   
// ...
 };
 
 class Square : public Shape {
 public:
   
// ...
   virtual Shape* clone() const { return new Square(*this); }
   
// ...
 };

现在假设每个 Fred 对象有一个 Shape对象。Fred对象自然不知道 Shape是圆还是矩形还是……。Fred的拷贝构造函数和赋值操作符将调用Shapeclone()方法来拷贝对象:

 

 class Fred {
 public:
   Fred(Shape* p) : p_(p) { assert(p != NULL); }   
// p must not be NULL
  ~Fred() { delete p_; }
   Fred(const Fred& f) : p_(f.p_->clone()) { }
   Fred& operator= (const Fred& f)
     {
       if (this != &f) {              
// 检查自赋值
         Shape* p2 = f.p_->clone();   
// Create the new one FIRST...
         delete p_;                   
// ...THEN delete the old one
         p_ = p2;
       }
       return *this;
     }
   
// ...
 private:
   Shape* p_;
 };

TopBottomPrevious sectionNext section ]


E-Mail E-mail the author
C++ FAQ LiteTable of contentsSubject indexAbout the author©Download your own copy ]
Revised Apr 8, 2001

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 类baseclass是一个抽象的概念,通常用于面向对象编程中。它是其他类的父类,包含了一些共同的属性和方法,可以被其他类继承和扩展。在程序设计中,类baseclass可以提高代码的重用性和可维护性,同时也可以方便地实现多态和封装等面向对象的特性。 ### 回答2: 在面向对象编程中,类是一个用来派生出其他子类的类。一个类也被称为父类或超类。在Python语言中使用class关键字定义类,包括类和派生类。 定义一个类baseclass,需要考虑以下几个方面: 1. 类名:我们可以给类定义一个有意义的类名,用于表示它是一个类。 2. 属性:类中可以定义一些属性,供后续的子类使用。这些属性可以是类属性或实例属性。 3. 方法:类中可以定义一些方法,供后续的子类使用。这些方法可以是类方法、静态方法或实例方法。 下面是一个简单的示例代码,定义一个类Person,包括姓名、性别、年龄这三个属性和一个输出信息的方法。 ```python class Person: def __init__(self, name, gender, age): self.name = name self.gender = gender self.age = age def print_info(self): print(f"姓名:{self.name},性别:{self.gender},年龄:{self.age}") ``` 解释一下代码: - 第1行定义了类名Person,表示这是一个人类的定义。 - 第3行定义了类的构造函数__init__,用于初始化定义的属性。 - 第5-7行定义了三个实例属性name、gender、age,这些属性将会被继承给子类。 - 第9-11行定义了一个实例方法print_info,用于输出人类的属性信息。 有了类Person的定义,我们就可以创建一些派生类,比如学生类、教师类等等。这些派生类可以继承类Person中的属性和方法,也可以根据需要添加自己的属性和方法。由于继承的存在,可以减少代码的冗余,提高代码的复用性和可维护性。 总之,定义一个类需要考虑属性和方法的定义,是构成一个完整类的必要元素。类定义的规范和质量直接影响到后续子类的实现和使用。 ### 回答3: 8-8题要求定义一个类baseclass,类是面向对象编程中继承础,也叫做父类或超类。类是所有派生类的共性部分,定义类可以使派生类间的代码共享达到最大化,提高代码的可扩展性和可维护性。下面我来详细介绍如何定义一个类baseclass,具体如下: 一、类的构造函数: 定义一个类要先定义它的构造函数,构造函数是类的初始化函数,当我们创建一个实例时,调用构造函数来完成对象的初始化。 二、类的数据成员: 在类中定义该类实例的常用数据属性或本属性。 三、类的成员函数: 在类中定义该类实例的本操作函数或本公共操作函数。 四、类的析构函数: 析构函数负责清理对象分配的内存,释放对象所使用的资源。 五、友元函数: 如果某些函数需要在不继承类的情况下访问类的成员或私有成员变量,就需要使用友元函数,友元函数不是类的成员函数,但是却可以访问类中的私有成员。友元函数放在类的声明中,前面加上friend关键字。 以上就是定义一个类baseclass的主要方法,当我们在开发具体应用时,只需要继承该类,然后添加自己的成员和函数,就可以非常方便地完成代码的开发。同时,根据不同的业务需求,我们可以很方便地更新类的定义,达到代码的重构和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nicrosoft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值