2012年9月9日
#
加入继承关系是private 编译器不会自动把derived class 转换成base class@import url(http://www.cppblog.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
2012年9月6日
#
3D Game ENGINE DISIGN 66-67,原先在看的时候一直很没明白,test for nonintersection和test for intersection,该书中又把它称作不费力检测和费力检测。一开始一直不明白这两个不是一样的道理吗,图2.22给了个test for nonintersetion的例子,我当时就把它死记这个例子就是test for noninterstion。
今天,才发现他的test for nonintersection的意思其实是不完全能把intersection 检测出来,也可以这么理解test for nonintersection 他检测出来的,culled掉后,可能还有几个object遗漏下来,其实这几个object也是需要culled,但是数量不多,因此这种也可以叫做不费力检测
2012年9月5日
#
template <class T>
T* DynamicCast(object* obj)
{
return obj&& obj->IsDerived(T::TYPE)?(T*)obj:0;
现在有class A, class B,class C
继承关系如下:
class A
{
}
class B:public A
{
}
class C:public B
{
}
DynamicCast的定义就是安全向下转换,我一开始认为一个基类的对象用dynamiccast转换到子类这样会是安全的;
如 A *a; B*b; b=DynamicCast(a);这样转换b得到其实是0?其实这样才是真正做到安全,因为B*b只是指向B类的指针,它指向的内容是没有继承部分的,转换到B类,那就会出错。那么dynamiccast有什么用呢?
考虑下面这种情况
void cast(B* pkb)
{
C* c = DynamicCast(pkb);
//........
}
C* m_c;
//可能某个时候转换成了B
cast(m_c);这样调用的时候,函数内部用了dynamicCast保证,传进来虽然是B类型的,其实它是C类型的,但是某个时候转换成了B,因此这个指向B类的指针指向的内容其实也是有他的继承部分的,因此这样转换就没有问题。
2012年8月29日
#
在c++教科书中,学习虚析构函数的时候经常会涉及到基类继承等,许多代码也经常把基类的析构函数设置成虚函数,但是有的时候也不一定为虚。那么何时析构函数要设置成虚呢?
简单总结下要用多态的时候就得用虚析构函数。
class shape
{
public:
shape();
~shape();
}
class renctangle:public shape
{
public:
rectangle();
~rectangle();
}
假如我们在应用当中,只会用到继承类,也就是renctangle *a = new recrangle;
之后只用这个a就可以完成功能,那么基类就不用虚析构函数了。
但是,我们有的时候,经常把renctangle指针强制转换成基类,然后用基类的函数操作。最后delete 基类指针,那么这个时候,就必须用虚析构函数。
2012年8月28日
#
最近在调试一段代码发现几个问题:
class test
{
public:
testtest(){}
testtest(int a);
testtest(const testtest& c );
}
有某个函数如何下
void create(const test& a)
{
}
调用如下:
create(1) 这样使用编译通过了,而且会调用testtest(int a)的构造函数
然后我就像把create的const去掉试一下
create(test& a)结果编译错误
我就想加了const为什么会调用构造函数?
当然create(test a)这样肯定也是会调用构造函数的。之后我就猜想 函数参数const testest& c和testtest c是允许有临时变量产生因此允许调用构造函数。testtest& 只是想引用是不会调用构造函数的。
但是我又想const testets& 为什么要弄个临时变量呢,因为函数内对const引用改变 会有报错的,可能是为了安全吧,仅仅猜想,vs2008调试
2012年8月27日
#
int iQuantity = (int)m_kInfoArray.size();
for (int i=0; i< iQuantity; i++)
{
const Info& rkInfo = m_kInfoArray[i];
if (rkInfo.User == pkUser&& rkInfo.ID == pkID)
{
if (i < --iQuantity)
{
m_kInfoArray[i] = m_kInfoArray[iQuantity];
}
m_kInfoArray.pop_back();
return;
}
}
在读这段代码的时候 我对作者用 i< --iQuantity不是很理解,这样对代码阅读性不是很高,让我来写肯定是:
if (i < (iQuantity-1))
{
m_kInfoArray[i] = m_kInfoArray[iQuantity-1];
}
m_kInfoArray.pop_back();
iQuantity--;
这样的话一不改变iQuantity的值,他就是数组的长度,而且iQuantity-1就是数组最后一个,最后pop时候再iQruantity--,虽然这样代码行数多了,但是比较容易理解。后来发现作者是很注重代码高效性的人,的确游戏引擎的代码就是要尽可能高效。我这句i < (iQuantity-1) 很明显iQuantity-1先生成一个临时变量然后再去和i比较,这里就浪费了。而作者的代码是没有一点浪费的。
2012年8月26日
#
看到一个c++对象构造的一个细节,平时在写代码的时候都没有注意。
对象的成员变量的初始化动作发生在进入构造函数本体之前。