dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
阅读:936回复:10

C++ 虚拟构造函数

楼主#
更多 发布于:2003-12-30 14:30
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 来探讨一下  
当个好的屠夫一直是我的梦想
ApH
ApH
知名人士
知名人士
  • 铜币0枚
  • 威望0点
  • 贡献值0点
1C#
发布于:2003-12-30 16:58
Re: C++ 虚拟构造函数
我也了解了一下,但是没有找到什么具体的例子,但是按照“它们”的说法,其实就是一个Factory Method Pattern,所谓的虚拟构造函数实际上就是Creator::FactoryMethod(),而用户提供的就是ConcreteCreator::FactoryMethod()。

对于C++我觉得就是这样,但感觉上ObjectPascal的方法和Java的应该比较接近,关键是“类类型”。

在Java中的Class类,不知道能否充当“类类型”,但是虚拟构造函数的意义是什么?为什么要对构造函数进行虚拟?我认为虚拟的目的是为了override,可是对于构造函数为什么要override?

不想不知道,越想越糊涂!
kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
2C#
发布于:2003-12-30 20:12
Re: C++ 虚拟构造函数
这种类型的应用是有用的,我的新图形库里面作了一Object factor,其中有一个复制功能,即根据一个任意的对象(当然也不那么任意,必需是BaseObject的派生类的对象),产生一个新的完全相同的对象,注意工厂可不知道它是属于那个具体的类,产生的对象要存储在图形库中,如何实现?我的方法和他们的不同,是用typeid实现的.
不要只注重名词,明年搬家后把这个库放到cvs上你看看. [ 2003-12-30 20:14:44 kmwang 修改 ]
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
3C#
发布于:2003-12-30 20:41
Re: C++ 虚拟构造函数
虚拟 允许我们调用某个函数,对于这个函数,仅仅知道它的接口,而不知道具体的对象类型。
我们有对象的 指针 或 引用, 但不知道对象真正的类型时, 用虚拟函数来完成因类型而异的行为.
看 More Effective C++ 对 virtual constructor 的定义:
是某种函数, 视其获得的输入, 可产生不同型别的对象.
连函数自身是否是虚拟都不做要求
糊涂啊

觉得楼顶算不上是 virtual constructor. 我直接把它理解成 virtual Creator.

[ 2003-12-30 20:57:25 dabou 修改 ]
当个好的屠夫一直是我的梦想
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
4C#
发布于:2003-12-30 20:45
Re: C++ 虚拟构造函数
不要只注重名词

呵呵, 是啊

源码我可以看吗?
当个好的屠夫一直是我的梦想
kmwang
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
5C#
发布于:2003-12-30 22:08
Re: C++ 虚拟构造函数
可以,不过现在还没完成,而且还比较庞大.
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
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也不会提供这样直接的支持.都需要额外的代价.因为虚拟和构造本身是有冲突的.好象没有一种直接简单的变通方案.要么变丑了,要么变复杂了:((
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
dabou
小有名气
小有名气
  • 铜币0枚
  • 威望0点
  • 贡献值0点
7C#
发布于:2003-12-31 09:11
Re: C++ 虚拟构造函数
你这么一说我倒是比较清晰:)
当个好的屠夫一直是我的梦想
ApH
ApH
知名人士
知名人士
  • 铜币0枚
  • 威望0点
  • 贡献值0点
8C#
发布于:2003-12-31 10:29
Re: C++ 虚拟构造函数
看来还是太注重名字了,Design Pattern 上的 Fectory Method 的别名就是 Virtual Constructor。这样就清楚了。
mumu
写手
写手
  • 铜币0枚
  • 威望0点
  • 贡献值0点
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++那样理解并非如是)
这样我们就可以任意的对生成类的方式做改变.也不用建什么子类索引表等额外的负担.
王小波说:“中年妇女在中国是一种自然灾害,这倒不是因为她们不好看,而是因为她们故意要恶心人。” 一天,我乘坐公交车,一位MM突然转过头来对我说:“你帅吗?”我说:“我不帅!”MM突然给我一巴掌,并说:“我最讨厌说谎的人了!” 如果你更热爱金钱而非自由,更习惯于被奴役的安宁而畏惧令人充满活力的争取自由的抗争,那么,请你静静地走开。我们不会乞求你的建议或是帮助。伏下身去讨好那喂养你的人吧。但愿身上的锁链不会给你造成太多的痛苦,但愿未来的人们不会记起你曾经是我们的国人 Samuel Adams: 18世纪美国独立革命重要领袖,著有“殖民者的权利”
slw4qd
著名写手
著名写手
  • 铜币2枚
  • 威望0点
  • 贡献值0点
10C#
发布于:2004-01-02 06:18
Re:C++ 虚拟构造函数
不懂
游客

返回顶部