设为首页 加入收藏

TOP

C++从零开始(十一)(下)――类的相关知识(二)
2014-11-24 13:20:07 】 浏览:9704
Tags:从零 开始 十一 相关 知识
用收音机的人不关心调台是如何实现的,只关心怎样调台。因此,虚函数表示函数的定义不重要,重要的是函数的声明,虚函数只有在派生类中实现有意义,父类给出虚函数的定义显得多余。因此C++给出了一种特殊语法以允许不给出虚函数的定义,格式很简单,在虚函数的声明语句的后面加上“= 0”即可,被称作纯虚函数。如下:
class Food; class Animal { public: virtual void Gnar() = 0, Eat( Food& ) = 0; };
class Cat : public Animal { public: void Gnar(), Eat( Food& ); };
class Dog : public Animal { void Gnar(), Eat( Food& ); };
void Cat::Gnar(){} void Cat::Eat( Food& ){} void Dog::Gnar(){} void Dog::Eat( Food& ){}
void main() { Cat cat; Dog dog; Animal ani; }
上面在声明Animal::Gnar时在语句后面书写“= 0”以表示它所映射的元素没有定义。这和不书写“= 0”有什么区别?直接只声明Animal::Gnar也可以不给出定义啊。注意上面的Animal ani;将报错,因为在Animal::Animal中需要填充Animal的虚函数表,而它需要Animal::Gnar的地址。如果是普通的声明,则这里将不会报错,因为编译器会认为Animal::Gnar的定义在其他的文件中,后面的连接器会处理。但这里由于使用了“= 0”,以告知编译器它没有定义,因此上面代码编译时就会失败,编译器已经认定没有Animal::Gnar的定义。
但如果在上面加上Animal::Gnar的定义会怎样?Animal ani;依旧报错,因为编译器已经认定没有Animal::Gnar的定义,连函数表都不会查看就否定Animal实例的生成,因此给出Animal::Gnar的定义也没用。但映射元素Animal::Gnar现在的地址栏填写了数字,因此当cat.Animal::Gnar();时没有任何问题。如果不给出Animal::Gnar的定义,则cat.Animal::Gnar();依旧没有问题,但连接时将报错。
注意上面的Dog::Gnar是private的,而Animal::Gnar是public的,结果dog.Gnar();将报错,而dog.Animal::Gnar();却没有错误(由于它是虚函数结果还是调用Dog::Gnar),也就是前面所谓的public等与类型无关,只是一种语法罢了。还有class Food;,不用管它是声明还是定义,只用看它提供了什么信息,只有一个――有个类型名的名字为Food,是类型的自定义类型。而声明Animal::Eat时,编译器也只用知道Food是一个类型名而不是程序员不小心打错字了就行了,因为这里并没有运用Food。
上面的Animal被称作纯虚基类。基类就是类继承体系中最上层的那个类;虚基类就是基类带有纯虚成员函数;纯虚基类就是没有成员变量和非纯虚成员函数,只有纯虚成员函数的基类。上面的Animal就定义了一种规则,也称作一种协议或一个接口。即动物能够Gnar,而且也能够Eat,且Eat时必须给出一个Food的实例,表示动物能够吃食物。即Animal这个类型成了一张说明书,说明动物具有的功能,它的实例变得没有意义,而它由
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++从零开始(九)――何谓结构 下一篇C++从零开始(八)――C++样例一

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目