|
阅读:936回复:10
C++ 虚拟构造函数
Aph ,看虚拟构造函数了没?
我找了找, 发现他们把能产生新对象的函数, 就叫 构造函数 行为像 constructor, 能够产生不同类型的对象,他们把这样的技巧称作“虚拟构造函数”。 《The C++ Programming Language》,第三版,15.6.2 struct F { // interface to object creation functions virtual A* make_an_A() const = 0; virtual B* make_a_B() const = 0; }; void user(const F& fac) { A* p = fac.make_an_A(); // make an A of the appropriate type B* q = fac.make_a_B(); // make a B of the appropriate type // ... } struct FX : F { A* make_an_A() const { return new AX(); } // AX is derived from A B* make_a_B() const { return new BX(); } // BX is derived from B }; struct FY : F { A* make_an_A() const { return new AY(); } // AY is derived from A B* make_a_B() const { return new BY(); } // BY is derived from B }; int main() { user(FX()); // this user makes AXs and BXs user(FY()); // this user makes AYs and BYs // ... } 用了 Factory 模式的一个变体。user()被完全孤立开了——它对AX,AY这些类一无所知。 More Effective C++ 条款25 是说 虚拟构造函数的, 还说了个 virtual copy constructor. 但不知与 Object Pascal 的虚拟构造有什么不同, 叫 mumu 来探讨一下 |
|
|
|
1C#
发布于:2003-12-30 16:58
Re: C++ 虚拟构造函数
我也了解了一下,但是没有找到什么具体的例子,但是按照“它们”的说法,其实就是一个Factory Method Pattern,所谓的虚拟构造函数实际上就是Creator::FactoryMethod(),而用户提供的就是ConcreteCreator::FactoryMethod()。
对于C++我觉得就是这样,但感觉上ObjectPascal的方法和Java的应该比较接近,关键是“类类型”。 在Java中的Class类,不知道能否充当“类类型”,但是虚拟构造函数的意义是什么?为什么要对构造函数进行虚拟?我认为虚拟的目的是为了override,可是对于构造函数为什么要override? 不想不知道,越想越糊涂! |
|
|
2C#
发布于:2003-12-30 20:12
Re: C++ 虚拟构造函数
这种类型的应用是有用的,我的新图形库里面作了一Object factor,其中有一个复制功能,即根据一个任意的对象(当然也不那么任意,必需是BaseObject的派生类的对象),产生一个新的完全相同的对象,注意工厂可不知道它是属于那个具体的类,产生的对象要存储在图形库中,如何实现?我的方法和他们的不同,是用typeid实现的.
不要只注重名词,明年搬家后把这个库放到cvs上你看看. [ 2003-12-30 20:14:44 kmwang 修改 ] |
|
|
3C#
发布于:2003-12-30 20:41
Re: C++ 虚拟构造函数
虚拟 允许我们调用某个函数,对于这个函数,仅仅知道它的接口,而不知道具体的对象类型。
我们有对象的 指针 或 引用, 但不知道对象真正的类型时, 用虚拟函数来完成因类型而异的行为. 看 More Effective C++ 对 virtual constructor 的定义: 是某种函数, 视其获得的输入, 可产生不同型别的对象. 连函数自身是否是虚拟都不做要求 糊涂啊 觉得楼顶算不上是 virtual constructor. 我直接把它理解成 virtual Creator. [ 2003-12-30 20:57:25 dabou 修改 ] |
|
|
|
4C#
发布于:2003-12-30 20:45
Re: C++ 虚拟构造函数
不要只注重名词 呵呵, 是啊 源码我可以看吗? |
|
|
|
6C#
发布于:2003-12-31 01:02
Re: C++ 虚拟构造函数
我们想要这样的动作:
class A{}; class B:public A{}; 通过new A来产生B的实例. 1.如果class A的构造方法A()可以为virtual的话,这个任务就算完成了.但是,C++的面向对象语意决定了,构造对象时需要提供类的全部信息,保证可以在构造类时候建立vtable.所以C++不支持这样的语法.如果有,恐怕整个继承体系就极度混乱了吧.虚拟只要你提供一个抽象接口. 2.我好像是讲过DELPHI有虚拟构造方法:))我想我的意思是,class B的构造方法可以让超类A的构造方法短路吧.不象C++/JAVA一样,子类一定会执行超类的构造方法.Python跟DELPHI一样. 3.虽然不很确定,但我想即使是DELPHI也不会提供这样直接的支持.都需要额外的代价.因为虚拟和构造本身是有冲突的.好象没有一种直接简单的变通方案.要么变丑了,要么变复杂了:(( |
|
|
|
7C#
发布于:2003-12-31 09:11
Re: C++ 虚拟构造函数
你这么一说我倒是比较清晰:) |
|
|
|
8C#
发布于:2003-12-31 10:29
Re: C++ 虚拟构造函数
看来还是太注重名字了,Design Pattern 上的 Fectory Method 的别名就是 Virtual Constructor。这样就清楚了。 |
|
|
9C#
发布于:2003-12-31 17:33
Re:C++ 虚拟构造函数
我还是希望Python/Ruby这样动态语义的解释语言能够轻松的解决这样的困难.
类的所有属性和方法全部可以替换,比如Python: class A: def __init__ (self): print 'in self' class B(A): def go (self): print 'in B go' def go (m = 1): print 'in go' A.__init__ = go a = A() a.ago = go a.ago() a.bgo = B() a.bgo.go() --output.txt-- in go in go in go in B go 类A的构造方法(__init__)被动态替换为自已的函数. 属性bgo可以动态加入. (__init__可以看成是Python对象的构造方法,虽然按C++那样理解并非如是) 这样我们就可以任意的对生成类的方式做改变.也不用建什么子类索引表等额外的负担. |
|
|