C++面试笔记--面向对象
说到面向对象,大家第一反应应该就是它的三大特性:封装性、继承性和多态性。那么我们先简单的了解一下这三大特性:
(1)封装性:封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
在C++中类中成员的属性有:public, protected, private,这三个属性的访问权限依次降低。
(2)继承性:继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
(3)多态性:多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。实现多态,有二种方式,覆盖,重载。
覆盖,是指子类重新定义父类的虚函数的做法。
重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
1、C++中空类默认产生哪些类成员函数?
答案:
对于一个空类,编译器默认产生4个成员函数:
(1)默认构造函数
(2)析构函数
(3)拷贝构造函数
(4)赋值函数
2、结构是否可以有构造函数、析构函数及成员函数?如果可以,那么结构和类还有什么区别吗?
答案:
区别是class中变量默认是private,struct中的变量默认是public。class继承默认是private继承,而struct继承默认是public继承。struct可以有构造函数、析构函数,之间也可以继承甚至是多重继承,等等。C++中的struct其实和class意义一样,唯一不同就是struct里面默认的访问控制是public,class中默认访问控制是private。C++中存在struct关键字的唯一意义就是为了让C程序员有个归属感,是为了让C++编译器兼容以前用C开发的项目。
下面我们写一段struct中继承的例子。
- #include<iostream>
- using namespace std;
- enum Bread{Golden,Cairn,Dandie,SheTland,Lab};
- struct mannal{
- public:
- mannal():itsAge(),itsWeight(){}
- ~mannal(){}
- int getage()const {return itsAge;}
- void setage(int age){itsAge=age;}
- int getweight()const {return itsWeight;}
- void setweight(int weight){itsWeight=weight;}
- void speak()const{cout<<"mannal sound!"<<endl;}
- void sleep()const {cout<<"sleeping!"<<endl;}
- protected:
- int itsAge;
- int itsWeight;
- };
- struct dog:public mannal{
- private:
- Bread itebread;
- public:
- dog():itebread(Golden){}
- ~dog(){}
- Bread getbread()const {return itebread;}
- void getbread(Bread bread){itebread=bread;}
- void wagtail()const {cout<<"wagging!"<<endl;}
- void begforfood()const{cout<<"food!"<<endl;}
- };
- int main(){
- dog fido;
- fido.speak();
- fido.wagtail();
- cout<<"fiod is "<<fido.getage()<<"years old!"<<endl;
- return ;
- }
- #include<iostream>
3、下面程序哪个语句是错的?
- struct test{
- test(int){}
- test(){}
- void fun(){}
- };
- int main()
- {
- test a();//语句一
- test b();//语句二
- a.fun();//三
- b.fun();//四
- //答案选四,因为test b(),这个声明了一个函数,然而本意是想创建一个对象b,但是这个声明函数的错误在编译的时候是检测不出来的,所以就调用不了fun,所以四错误。
- }
- struct test{
- 4、下面程序打印出的结果是什么?
- #include<iostream>
- using namespace std;
- class base
- {
- private:
- int m_i;
- int m_j;
- public:
- base( int i ) : m_j(i),m_i(m_j) {
- base() : m_j(),m_i(m_j){}
- int get_i() {return m_i;}
- int get_j() {return m_j;}
- };
- int main ()
- {
- base obj();
- cout << obj.get_i() <<endl<< obj.get_j() <<endl;
- return ;
- }
解析:本题想得到的结果是“98,98”。但是成员变量的声明是先 m_i ,然后是 m_j;初始化列表的初始化变量顺序是根据成员变量的声明顺序来执行的,因此,先初始化 m_i,但此时 m_j 还未初始化,m_i 会被赋予一个随机值。改变一下成员变量的声明顺序可以得到预想的结果。
答案:
输出结果第一个为随机数,第二个是98。
- #include<iostream>
5、析构函数可以为 virtual 型,构造函数则不能,为什么?
答案:
虚函数采用一种虚调用的办法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,你势必要知道对象的准确类型,因此构造函数不能为 virtual。
6、如果虚函数是非常有效的,我们是否可以把每个函数都声明为虚函数?
答案:
不行,这是因为虚函数是有代价的:由于每个虚函数的对象都必须维护一个 v 表,因此在使用虚函数的时候会产生一个系统开销。如果仅是一个很小的类,且不行派生其他类,那么根本没必要使用虚函数。
6、哪一种成员变量可以在同一类的实例间共享?
答案:
必须使用静态成员变量在一个类的所有实例间共享数据。如果想限制对静态成员变量的访问,必须把它们声明为保护型或私有型。不允许用静态成员去存放某一个对象的数据。静态成员函数是在这个类的所有对象间共享的。如果静态成员数据设为私有的,可以通过共有静态和产能原函数访问。
7、编写类 String 的构造函数、析构函数和赋值函数。
- #include<iostream>
- using namespace std;
- class string{
- string(const char *str);
- string(const string &);
- ~string();
- string &operator=(const string &) ;
- private:
- char *m_data;
- };
- string::~string(){//析构函数
- delete []m_data;
- }
- string::string(const char *str){//构造函数,利用复制操作进行。
- if(NULL==str){
- m_data=new char[];
- *m_data='\0';
- }
- else{
- int length=strlen(str);
- m_data=new char [length+];
- strcpy(m_data,str);
- }
- }
- string::string(const string & a){
- int lenght=strlen(a.m_data);
- m_data=new char[length+];
- strcpy(m_data,a,m_data);
- }
- string & string::operator=(const string &a){
- if(this==&other){//检查自赋值
- return *this;
- }
- delete []m_data;//释放原有的内存资源。
- int length=strlen(a.m_data);//分配新内存资源,并复制内容
- m_data=new char[length+];
- strcpy(m_data,a.m_data);
- return *this;
- }
- #include<iostream>
8、重载与覆盖有什么不同?
答案:
虚函数总是在派生类中被改写,这种改写被称为“override”(覆盖)。
override 是指派生类重写基类的虚函数,重写的函数必须有一致的参数表和返回值。Override这个单词好像一直没什么合适的中文词汇来对应。有些人译为“覆盖”,还贴切一些。
overload约定成俗地被翻译为“重载”,是指编写一个与自己已有函数同名但是参数表不同的函数。例如一个函数既可以接受整型数作为参数,也可以接收浮点数作为参数。重载不是一种面向对象的编程,而是一种语法规则,重载与多态没什么直接关系。
9、为什么析构函数可以是virtual,但是构造函数不行呢?
答案:
虚函数采用的是一种虚调用的方法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道借口而不知道准确对象类型的函数,但是如果要创建一个对象你势必要知道对象的准确类型,因此构造函数不能为虚。
- 10、友元函数去实现两个点之间的距离,写一个poiny类
答案:
- #include<iostream>
- using namespace std;
- class point{
- private:
- double x,y;
- public:
- point(double a=0.0,double b=0.0):x(a,b){}
- friend double distance(point &left,point &right){}
- };
- double distance(point &left,point &right){
- return ((left.x-right.x)^+(left.y-right.y)^)^0.5;
- }
- #include<iostream>
- 11、最好不要从析构函数中抛出异常!!!,构造函数中可以抛出异常,虚方法中也是可以抛出异常的。
答案:
C++面试笔记--面向对象的更多相关文章
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...
- C#学习笔记——面向对象、面向组件以及类型基础
C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...
- Java高级开发工程师面试笔记
最近在复习面试相关的知识点,然后做笔记,后期(大概在2018.02.01)会分享给大家,尽自己最大的努力做到最好,还希望到时候大家能给予建议和补充 ----------------2018.03.05 ...
- php面试笔记(5)-php基础知识-自定义函数及内部函数考点
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而函数相关的考点 ...
- php面试笔记(3)-php基础知识-运算符
本文是根据慕课网Jason老师的课程进行的PHP面试知识点总结和升华,如有侵权请联系我进行删除,email:guoyugygy@163.com 在面试中,考官往往喜欢基础扎实的面试者,而运算符相关的考 ...
随机推荐
- CF Round 542 Div1.
B. Wrong Answer 构造一个长度为 2000 的数组,满足最大“子段和 $\times$ 子段长度”比最大子段和刚好大 k sol: 一个比较好的构造方法: 令数组总和为 $S$,然后构造 ...
- LeetCode Longest Uncommon Subsequence II
原题链接在这里:https://leetcode.com/problems/longest-uncommon-subsequence-ii/#/description 题目: Given a list ...
- lrzsz-串口传输文件
二.编译安装 1.解压文件,进入目录 tar –zxvf lrzsz-0.12.20.tar.bz cd / lrzsz-0.12.20 ./configure 2../con ...
- SQL 用;with 由所有的子节点查询到树结构中所有父节点
1.所有的子节点查询到树结构中所有父节点 RETURNS @Tree Table(PID )) as begin --DECLARE @ID VARCHAR() --SET @ID = ' ;with ...
- 卸载驱动时,没有/lib/modules目录
卸载驱动时,没有/lib/modules目录,怎么办? 答:没有这个目录,就创建这个目录! #rmmod spi_oled_drv #rmmod: chdir (/lib/modules): no ...
- C# 获取图片某像素点RGB565值
Project Source Download: http://download.csdn.net/detail/mostone/6360007 [csharp] view plain copy pu ...
- Byte和byte[]数组
Byte和byte[]数组,“表示一个 8 位无符号整数, 一般为8位二进制数”. Byte是计算机最基础的存储单位和最基础的通讯单位. 而所有的类型都是支持由byte[]类型转换而来. 为什么说By ...
- phonegap制作windows phone包
下载SDK win7及以下版本下载SDK http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=27570 WIN8下载SDK ht ...
- Java中Object.hashCode contract
面试时在这个问题上犯了个错误,只重写了equals方法,而没有覆盖hashCode()方法. 回来重读了Effective Java的Item 9,里面提到Object.hashCode contra ...
- ABP仓储
简介 我们都知道ABP已经实现了仓储模式,支持EF core 和dapper 进行数据库的连接和管理,可以很方便的注入仓储来操作你的数据,不需要自己单独定义一个仓储来实现,通用的仓储实现了通用的cru ...