关于面向对象的面试知识点整理(一)
例1: C++ 中的空类默认产生哪些类成员函数?
对于一个空类,编译器默认产生4个成员函数:默认构造函数、 析构函数、 拷贝构造函数和赋值函数。
例2: structure是否可以拥有constructor / destructor及成员函数?如果可以, 那么structure和class还有区别么?
区别是class中变量默认是private, struct中的变量默认是public。struct可以有构造函数,析构函数,之间也可以继承,等等。 C++中的struct其实和class意义一样, 唯一不同的就是struct里面默认的访问控制是public, class中默认的访问控制是 private。 C++中存在struct关键字的唯一意义就是为了让C程序员们有个归属感, 是为了让C++编译器兼容以前用C开发的项目。
例3: 现有以下代码, 则编译时会产生错误的是? struct Test { Test(int) {} Test() {} ~Test() {} void fun() {} }; int main() { Test a(1); a.fun(); Test b(); b.fun(); return 0; }
Test b() 这个语法等同于声明了一个函数,函数名为b, 返回值为Test, 传入参数为空。但是实际上,代码作者是希望声明一个类型为Test,变量名为b的变量,应该写成 Test b; , 但程序中这个错误在编译时是检测不出来的。出错的是 b.fun() ,它是编译不过去的。
例4: 下面程序的打印出的结果是什么? #include using namespace std; class Base { public: Base(int i) : m_j(i), m_i(m_j) {} Base() : m_j(0), m_i(m_j) {} ~Base() {} int get_i() const { return m_i; } int get_j() const { return m_j; } private: int m_i; int m_j; }; int main() { Base obj(98); cout << obj.get_i() << endl; cout << obj.get_j() << endl; return 0; }
本题想要得到的结果是"98,98"。 但是成员变量的声明是先m_i, 然后是m_j;初始化列表的初始化变量顺序是根据成员变量的声明顺序来执行的, 因此m_i会被赋予一个随机值。更改一下成员变量的声明顺序可以得到预想的结果。 如果要得到 "98,98"的输出结果,程序需要修改如下 int m_j; int m_i;
补充变量未初始化的值 未初始化的全局数组为0;未初始化的局部数组为随机值;初始化部分的全局数组与局部数组,初始化部分为初始化值,未初始化部分都为0;(不管全局还是局部)全局变量未初始化:#include using namespace std; int i; char c; float f; double d; int* p; int main() { cout << i << endl; // 0 cout << c << endl; // " " cout << f << endl; // 0 cout << d << endl; // 0 cout << p << endl; // 0 return 0; }局部变量未初始化为随机数。#include using namespace std; int main() { int i; char c; float f; double d; int* p; cout << i << endl; cout << c << endl; cout << f << endl; cout << d << endl; cout << p << endl; return 0; }类的成员变量为初始化的值对象在全局作用域或为静态局部对象时,类的内置成员变量被初始化为0.对象在局部作用域定义时,类的内置成员变量不被初始化为0。对于类型成员按照其自身的默认构造函数进行初始化。如果类显式提供了带参数的构造函数,则编译器不会再为其生成空参数的构造函数。这时候就不能用空参数来定义类型变量 class A{ public: int value; A (int i):value(i){} }; int main(){ A a; // error return 0; }
参考代码: #include using namespace std; class A { public: int i; float f; double d; char c; int* p; void print() { cout << i << endl; cout << c << endl; cout << f << endl; cout << d << endl; cout << p << endl; cout << "-------------------" << endl; } }; A a0; int main() { a0.print(); A a; a.print(); return 0; }
例5: MFC类库中,CObject类的重要性不言自明。在CObject的定义中,我们看到一个有趣的现象,即CObject的析构函数是虚拟的。为什么MFC的编写者认为虚拟的析构函数是必要的? #include using namespace std; class Base { public: Base() { cout << "Base" << endl; } ~Base() { cout << "~Base" << endl; } }; class Derived : public Base { public: Derived() { cout << "Derived" << endl; } ~Derived() { cout << "~Derived" << endl; } }; int main() { Base *b = new Derived(); delete b; return 0; }
我们将一个父类的指针指向子类的对象,当我们使用 delete b 去释放b指向的内存,会调用父类的析构函数(静态联编),但是却不会调用子类的析构函数。
如果子类对象在构造函数内申请了一块堆内存,最后根据上述情况则会造成内存泄漏,我们在 ~Base() { cout << "~Base" << endl; } 前 加上 virtual , delete b 会先调用子类析构,再调用父类析构,自然就把子类申请的内存释放掉啦!
补充知识: C++静态联编和动态联编
根据: https://blog.csdn.net/erlian1992/article/details/44262843 所修改
联编是指一个程序自身彼此关联的一个过程。 按照联编所进行的阶段不同,可分为静态联编和动态联编两种。
静态联编: 静态联编是指在程序编译链接阶段进行联编。这种联编又称为早期联编,这是因为这种联编工作是在程序运行之前完成的。
编译时所进行的联编又称为静态束定。束定是指确定所调用的函数与执行该函数代码之间的关系。 其优点是效率高,但灵活性差。
下面来看一个静态联编的程序例题: #include using namespace std; class Point { public: Point(double i,double j)//基类的构造函数 { x=i;y=j; } double Area() const//定义的常成员函数 { return 0.0; } private: double x,y; }; class Rectangle:public Point//公有继承的派生类 { public: Rectangle(double i,double j,double k,double l);//声明派生类的构造函数 double Area() const { return w*h; } private: double w,h; }; Rectangle::Rectangle(double i,double j,double k,double l):Point(i,j)//派生类构造函数的函数体 { w=k; h=l; } void fun(Point &s)//定义的类外函数 { cout< using namespace std; class Point { public: Point(double i,double j)//基类的构造函数 { x=i;y=j; } virtual double Area() const//定义的虚函数 { return 0.0; } private: double x,y; }; class Rectangle:public Point//公有继承的派生类 { public: Rectangle(double i,double j,double k,double l);//声明派生类的构造函数 virtual double Area() const//派生类的虚函数 { return w*h; } private: double w,h; }; Rectangle::Rectangle(double i,double j,double k,double l):Point(i,j)//派生类构造函数的函数体 { w=k; h=l; } void fun(Point &s)//定义的类外函数 { cout<
猛男犀牛智造上线,但商标都没提前注册?前几日还在引发众人猜测的阿里巴巴梅花鹿脚印,已于9月16日揭晓答案。是一只猛男犀牛,与已有的盒马形象相比,犀牛似乎只多了一只牛角,手拿绣花针,耐心地绣着一朵花,身着红色东北大花袄,
94年小叔叔的手机桌面94年小叔叔的手机桌面,我也不知道为什么买这么好的手机,桌面就这些软件,是不是太浪费资源了捂脸。。
这奶茶有点意思这奶茶有点意思,手打渣男林檬,我想说这是什么理由取得这个名字,很新奇哦。
置物架,需要的联系爽快的来,全新货物架,没有动过,完好无损,螺丝全在长度是,,一米七高,宽度是,,99厘米宽,,需要的打包带走,支持同城交易,一共三层全新,包邮,蓝色的货物架就跟黄色货物架一样,仓库
手机端居然可以跟电脑端连接玩英雄联盟可能你不相信,但是事实就摆在你眼前,没错,你没有看错,手机端可以跟电脑端一起同步玩英雄联盟排位,画质流畅,而且还不卡,虽然屏幕小了一点,丝毫不影响发功,不坑电脑端的玩家,实时同步,
这真的能拿到吗?今天心血来潮弄了一下某拼的东西,实在无话可说了,本来只差0。01元了,然后拉了一个朋友,居然给我整0。008元捂脸捂脸捂脸捂脸捂脸捂脸捂脸捂脸捂脸这是搞那样,朋友圈都发到了,就是拿
道路千万条,安全第一条,行车不规范,亲人两行泪骑车要注意安全,眼观四方,千万不能分神,生命只有一次,还是希望那些年纪大的人不要骑车,实在太危险了,比较年纪大了,反应也慢,最后走路行驶,道路千万条,安全第一条,行车不规范,亲人两
这贷款好慌,该怎么办这种情况改怎么办,这是我一个朋友。。
美国商标官费上涨正式实施日期实锤啦美国专利商标局(USPTO)最新发布,终于确认了针对美国商标官费调整的具体实施日期官费上涨将于2021年1月2日开始执行!针对美国商标和外观设计的官费上涨的消息自今年六月份起就闹得
天生BUFF华硕主板惊艳ROG2019新品发布会2019年7月23日,ROG玩家国度在北京凯迪拉克M空间召开了天生BUFFROG2019新品发布会。秉承只为超越的电竞信仰,ROG产品始终引领行业潮流。此次发布会共发布了包括PC游
2019ROG新品发布会BUFF信仰,电竞显示器帧速全释放2019ROG新品发布会BUFF信仰,电竞显示器帧速全释放2019年7月23日,ROG玩家国度在北京凯迪拉克中心M空间召开天生BUFFROG新品发布会。华硕集团董事长施崇棠华硕共同