在对象的世界里,有一个特殊的指针,它叫做this。我们从来没有见过它,但是它却从来都存在。我们通过一个典型的例子来认识它:
class Human
{
public:
char fihc;
Human(char fishc);
};
Human::Human(char fishc)
{
fishc = fishc;
}
我们看到,在“fishc = fishc”之前,所有的语法都没有任何问题:
- Human()构造器有一个名为fishc的参数
- 虽然它与Human类里的属性同名,但却是不相干的两样东西,所以并没有错
- 可是,问题是怎么才能让构造器知道哪个是参数,哪个是属性呢?
这时候,就需要用到它了-this指针
this -> fishc = fishc
this指针的意思是指向当前的类生成的对象。现在编译器就懂了,赋值操作符的左边将被解释为当前对象的fishc属性,右边将被解释为构造器的传入来的fishc参数。
注意:
使用this指针的基本原则是:如果代码不存在二义性隐患,就不必使用this指针!
继承
继承是面对对象编程技术的一个核心概念,它使传统的软件开发模式发生了革命性的变化。
继承机制使得程序员可以创建一个类的堆叠层次结构,每个子类均将继承它的基类里定义的方法和属性。
那么它究竟有什么用呢?
简单来说,通过继承机制,程序员可以对现有的代码进行进一步扩展,并应用在新的程序中。
基类和子类
例子:一只乌龟和一只猪,都属于动物,有共同点,例如吃饭睡觉,也用不同点,乌龟会游泳,猪会上树。
那么我们需要编写一个Animal类作为Turtle类和Pig类的基类。
基类:
- 基类是可以派生出其他的类,也称为父类或者超类。比如这里的Animal类是基类
子类
- 子类是从基类中派生出来的类,比如这里的Turtle类和Pig类是子类
那么Animal类就拥有了Turtle类和Pig类的共同特征:吃东西、睡觉。
这里我们把这些动作都抽象为方法
- eat(),sleep()
而swim()方法在Turtle类实现,climb()方法在Pig类实现
动物都有嘴巴,而嘴巴是名词不是动作,所以要翻译成类的属性,而不是方法
我们将mouth转变为Animal类的一个成员变量(属性)。
接下来,我们要把对继承关系转化为C++代码,这需要使用如下所示的语法:
class SubClass : public SuperClass{...}
这里的SubClass是子类,SuperClass是基类。
上面的也就变成了:
class Pig : public Animal{...}
来一个总的例子:
#include <iostream>
#include <string>
class Animal
{
public:
std::string mouth;
void eat();
void sleep();
};
class Pig : public Animal
{
public:
void climb();
};
class Turtle : public Animal
{
public:
void swim();
};
void Animal::eat()
{
std::cout << "I'm eatting" << std::endl;
}
void Animal::sleep()
{
std::cout << "I'm sleeping! Don't disturb me!" << std::endl;
}
void Pig::climb()
{
std::cout << "我会上树" << std::endl;
}
void Turtle::swim()
{
std::cout << "我会游泳" << std::endl;
}
int main()
{
Pig pig;
Turtle turtle;
pig.eat();
turtle.eat();
pig.climb();
turtle.swim();
return 0;
}