结构函数中的this指针
副标题#e#
——————————-道理——————————-
某些人认为不该该在结构函数中利用this指针,因为这时this工具还没有完全形成。
可是,只要小心,是可以在结构函数中利用this指针的:
●在函数体中
●初始化列表中
因为“工具还没有完全形成”不料味着“什么都没有”。
在进入结构函数(及其chaining)之前,Compiler会:
●给class的instance分派内存
●成立运行时刻系统所需的信息(如vtbl等)
●##缺省地## 结构所有类成员
—————————–【能】———————————
结构函数的函数体(或结构函数所挪用的函数)【能】靠得住地会见:
●基类中声明的数据成员
●结构函数所属类声明的数据成员
这是因为所有这些数据成员被担保在结构函数函数体开始执行时已经被完整的成立。
—————————–【不能】———————————
结构函数的函数体(或结构函数所挪用的函数)【不能】向下挪用:
●被派生类重界说的虚函数
这是因为在基类的结构函数执行期间,“工具还不是一个派生类的工具”。
—————————【有时】———————————–
以下是【有时】可行的:
#p#副标题#e#
●通报 this 工具的任何一个数据成员给另一个数据成员的初始化措施
你必需确保该数据成员已经被初始化。好动静是你能利用一些不依赖于你所利用的编译器的显著的语言法则,来确定谁人数据成员是否已经(可能还没有)被初始化。坏动静是你必需知道这些语言法则(譬喻,基类子工具首先被初始化(假如有多重和/或虚担任,则查询这个序次!),然后类中界说的数据成员按照在类中声明的序次被初始化)。假如你不知道这些法则,则不要从this工具通报任何数据成员(岂论是否显式的利用了this要害字)给任何其他数据成员的初始化措施!假如你知道这些法则,则需要小心。
—————————-用途———————————-
好的OO设计强调“高聚合”,这样会发生许多小的责任单一的工具(其实“单一责任原则”基础就是最基本的OO原则)。
那么,小工具之间的协作就需要设置(其实“协作可设置”自己就是我们但愿的机动性地址):
●好比Observer模式中subject和observer的协作需要调subject.RegistorObserver(observer)来设置
●再好比多媒体框架DirectShow中filterGraph和videoWindow的协作需要调filterGraph.SetVideoWindow(videoWindow)来设置
而结构函数是很典范的设置机缘,举譬喻下:
class CMyWindow : public CWnd
{
private:
CFilterGraph filterGraph;
public
CMyWindow() { filterGraph.SetVideoWindow(this); };
};
————————–附录————————————
顺便总结基本常识
表一 | |
who | be called |
普通函数 | class::fun() |
结构函数 | superclass::superclass() ==〉subclass::subclass() |
析构函数 | subclass::~subclass() ==〉superclass::~superclass() |
表二 | ||
who | where | be called |
非虚函数 | everywhere | class::fun() |
虚函数 | 普通函数 | obj.vfun() |
虚函数 | 结构函数 | class::vfun() |
虚函数 | 析构函数 | class::vfun() |
需要明白的是,【结构/析构/普通】和【虚/非虚】是完全独立的分类方法:
●只要是“结构/析构”就“串联(chaining)”
●只要是“虚函数”就“大概obj.vfun()”
它们可以“一起生效”但“不相互滋扰”,好比虚析构函数的环境,看下面的例子:
class superclass
执行
{
virtual ~superclass() { println("superclass::~superclass()") };
};
class subclass : public superclass
{
virtual ~subclass() { println("subclass::~subclass()") };
};superclass * super = new subclass();
的功效是打印出
delete super;subclass::~subclass()
superclass::~superclass()
这意味着当执行delete super;时:
●是否是chaining式call呢?是。因为是析构函数。
●那chaining call从那边开始呢?从subclass::~subclass() ==〉superclass::~superclass(),
因为superclass * super的实际工具的范例是subclass。