面试01

今天面试了艺动娱乐,小弟还没到这种大公司面试过,心里有有些小紧张。艺动的架势确实也与小弟之前面试的公司不一样,虽然感觉今天的面试多半会被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_class

DEFINE_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中。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值