面试01

来源:互联网 发布:剑网三捏脸数据萝莉 编辑:程序博客网 时间:2024/06/05 08:40

今天面试了艺动娱乐,小弟还没到这种大公司面试过,心里有有些小紧张。艺动的架势确实也与小弟之前面试的公司不一样,虽然感觉今天的面试多半会被Pass掉,但是,多少也算有了点大公司面试的经验。

之前一直在小公司做单机游戏,项目经验也不足,最主要还是自己学东西不求甚解,知识面太窄,导致今天的面试非常惨淡!!!大哭

先总结下经验:自己虽然也用C++开发1年多了,但是,对C++的特性还是不够了解,C++底层的东西理解还是不够。今天,面试官问了我三个关于C++的问题,我竟然一个都不会。真是羞愧,吃一堑,长一智,先在这里记录下吧!

1.C++的菱形继承问题:

先写一个简单的例子:

#include <iostream>using namespace std;class A{public:private:};class B : public A{public:private:};class C : public A{public:private:};class  D : public B, public C{public:private:};int main(){return 0 ;}


这样A,B,C,D四个类就是一个菱形继承的关系,D中会保留两个A对象,这样会占用双倍的内存。同时,当A中有属性和函数的时候还可能会出现二义性问题。

将B,C类的代码改成如下就能解决菱形继承问题:

class B :  virtual public A{public:private:};class C : virtual public A{public:private:};

但是,并不能解决二义性问题。

解决二义性问题,需要从D类中入手,可以在D中实现同样的属性或者方法,指出调用的是B的还是C的,或者是什么时候调用B的什么时候调用C的。

或者,在调用的时候指明,调用的是C的方法,还是B的方法。


2.C++反射机制的实现

听到这个问题的时候,真的有点懵,因为,我之前只是听说过Java的反射机制(而且还忘了怎么实现),现在让我说C++如何实现反射机制,顿时不知道如何入手了。

回来在网上找了找,还真有,真是感谢网上的各位大神啊!

http://blog.csdn.net/nighsen/article/details/6407017

http://blog.csdn.net/cen616899547/article/details/9317323

这两位位大神的博客很详细。非常感谢!!!

下面是我仿照两位大神的方法的实现:

ReFactory:工厂类

.h

#ifndef _RE_FACTORY_H_#define _RE_FACTORY_H_#include   <string>  #include   <map>  #include   <iostream>using namespace std;typedef void* (*CreateFuntion)(void);//<回调函数//@biref 设计为单例类class ReFactory {public:static ReFactory * s_pReFactory ;static ReFactory * getInstance() ;public:ReFactory (){}~ReFactory (){}void* getClassByName(string name) ;void registClass(string name,CreateFuntion func) ;private:std::map<string,CreateFuntion> m_classMap ;};#endif

.cpp

#include "ReFactory.h"ReFactory * ReFactory::s_pReFactory = NULL ;ReFactory * ReFactory::getInstance(){if (s_pReFactory == NULL){s_pReFactory = new ReFactory() ;}return s_pReFactory ;}void* ReFactory::getClassByName(string name){std::map<std::string,CreateFuntion>::const_iterator itor ;itor = m_classMap.find(name) ;if (itor == m_classMap.end()){return NULL ;}else{return itor->second() ;}}void ReFactory::registClass(string name,CreateFuntion func){m_classMap.insert(std::make_pair(name,func)) ;}

ReRegister

.h

#ifndef _RE_REGISTER_CLASS_H_#define _RE_REGISTER_CLASS_H_#include "ReFactory.h"class ReRegisterClass {public:ReRegisterClass (string name,CreateFuntion func){ReFactory::getInstance()->registClass(name,func) ;}~ReRegisterClass (){}private:};template<class T,const char name[]>class ReRegister{public:ReRegister(){const ReRegisterClass temp = rc ;}~ReRegister();static void* createInstance() {return new T ;}public:static const ReRegisterClass rc ;};template<class T,const char name[]>const RegistyClass ReRegister<T,name>::rc(name,ReRegister<T,name>::createInstance()) ;#define  DEFINE_RE_CLASS(class_name)\char nameArray[]=#class_name;\class class_name:public ReRegister<class_name,nameArray> #define DEFINE_RE_CLASS_EX(class_name,father_class) \char nameArray[]=#class_name;\class class_name:public ReRegister<class_name,nameArray>,public father_classDEFINE_RE_CLASS(Coco){public:void Display(){printf("Coco");}};#endif

main

#include "Factory.h"#include "ReRegistClass.h"#include "ReFactory.h"int main(){Coco * co = (Coco*)ReFactory::getInstance()->getClassByName("Coco") ;co->Display() ;getchar() ;return 0;}

这样就OK了!!

虽然实现了反射,但是,这也不是真正意义上的反射,真正意义上的反射只有java,C#那种有虚拟机的语言才能实现。

3.C++lambad表达式

lambad表达式又叫匿名函数,在我看来就是能直接把函数体写在参数中了。

Lambda表达式是定义一个没有名称,也不需要显示类定义的函数对象。一般用来将函数作为实参传递到另一个函数。

相比于定义和创建一个常规的函数对象而言,lambda表达式非常容易使用和理解,而且需要的代码也较少。

[](double x){return x*x*x;}

[]lambda的引导,它标志着lambda表达式的开始,()是lambda表达式的参数列表。lambda表达式不允许有默认参数,而且,参数列表的长度是不可变的。{}lambda表达式的主体,可以包含多条语句。返回值类型可以指定,默认为void.

引导中可以包含一个捕获子句,用来确定lambda主题如何访问封闭作用域中的变量。

如果,没有符号,代表表面封闭作用域没有可以让lambad中访问的变量,如果有,可写成[=],这种情况下,可以访问,但是不能改变原始值。写成[&]可以改变。

若要捕获一个特定的对象[&name]需要这样写,多个用逗号分开。

测试代码:

#include <iostream>#include   <string>  #include <algorithm>#include <vector>int main(){int x = 4;int y = 5;int z = 0 ;z = []{return 10 + 10 ;}() ;//<普通z = [=]{return x + y;}() ;//<捕获但不改变z = [&]{x += 10 ; return x + y ;}() ;//<捕获,改变z = [&x,y]{x += 10  ; return x + y;;}() ;//<捕获,改变特定值z = [=]() mutable ->int { x += 10 ;return x + y; }();//<捕获,不改变原始值printf("x:%d;z:%d",x,z) ;getchar() ;return 0 ;}


4.C++是不是类型安全的编程语言?

答案是否定的。C++不是类型安全的编程语言,在C++中0和1是可以当作bool类型来使用的,但是,在类型安全的编程语言中是不能这样使用的,比如在Java中。



0 0