CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

构造函数和析构函数规模应该尽可能小型化?????

楼主yujianxueren(.)2003-08-01 00:58:03 在 .NET技术 / C# 提问

在VCKBASE.COM   中看到如下文章:  
  原文:  
   
  在设计类的时候,应该考虑今后有一天这个类可能成为其它类的基类。当从某个基类派生类的时候,基类的析构和构造函数分别被暗中拷贝到派生类的构造函数和析构函数。与普通的成员函数相反,它们可以被改写(假设它们是虚拟的)或者完全不调用,基类的构造函数和析构函数是自动被调用的。所以最好不要强制派生对象之所不欲,而是一定要使用它。换句话说,构造函数和析构函数实现的功能应该最小化,构造和销毁,不要画蛇添足。例如,对于一个支持序列化(将内容写入文件)的串类,不要在其构造函数中打开/创建文件。这种操作应该留给专门的成员函数来做,所以当创建新的派生类时,如   ShortString(用于保存定长串,像文件名),其构造函数将不会被强制实现任何多余的从基类继承的文件I/O操作。  
   
  原文结束-----------  
  我的疑惑:  
  1。"当从某个基类派生类的时候,基类de构造函数被暗中  
        拷贝到派生类的构造函数"中去??  
        不会吧?  
          如果我有:  
  class   A  
  {  
          int   i,j;  
          public   A(int   i1,int   j1)  
          {  
                  i=i1;  
                  j=j1;  
          }  
        public   A(int   i1)  
        {  
                  i=i1;  
                  j=0;  
        }  
  }  
   
  class   B   ;   A  
  {  
        public   b(int   i1,int   j1)  
        {  
                  i=i1+100;  
                  j=j1+199999;  
        }  
  }  
  试问怎么个拷贝法?????  
   
   
  2."基类的构造函数是自动被调用的"  
        果真如此的话,那么我在msdn上发现:  
        public   Cylinder(double   radius,   double   height):   base(radius,   height)  
        {  
          }  
        其中Cylinde是Cshape的派生类  
        那么既然是“自动调用”,我何不写成  
        public   Cylinder(double   radius,   double   height)  
        {  
        }  
        要不怎么说是“自动调用”呢??  
      注意我这里反复强调“自动”  
   
   
         
         
     
   
   
  问题点数:100、回复次数:7Top

1 楼TheAres(班门斧)回复于 2003-08-01 01:28:19 得分 100

1,你看看如下的程序,在产生一个B对象的时候,是会先调用B的父类的构造函数。如果不是把父类A中的函数在B中实现,如何执行。所以肯定是拷贝的,只不过是隐含的。具体拷贝过去函数是什么,这个不知道,我猜想大约是什么***Init***的函数。  
   
  //   cs_attribute_obsolete.cs  
  //   CS0619   expected  
  using   System;  
  class   A  
  {  
  public   int   i,j;  
  public   A()  
  {  
  Console.WriteLine("A:A()");  
  }  
  public   A(int   i1,int   j1)  
  {  
  i=i1;  
  j=j1;  
  Console.WriteLine("A:A(int,int");  
  }  
  public   A(int   i1)  
  {  
  i=i1;  
  j=0;  
  Console.WriteLine("A:A(int)");  
  }  
  }  
   
  class   B   :   A  
  {  
  public   B(int   i1,int   j1)  
  {  
  i=i1+100;  
  j=j1+199999;  
  Console.WriteLine("B:B(int,int)");  
  }  
   
  }  
  class   C  
  {  
  public   static   void   Main()  
  {  
  B   b   =   new   B(1,1);  
  Console.ReadLine();  
  }  
  }  
   
   
  2."基类的构造函数是自动被调用的"  
  什么不写就是自动调用。你显式的指定就不会自动了。  
  public   Cylinder(double   radius,   double   height)//自动  
        {  
        }  
   
  public   Cylinder(double   radius,   double   height):   base(radius,   height)//显式  
        {  
          }  
   
  Top

2 楼yujianxueren(.)回复于 2003-08-01 11:07:01 得分 0

To     TheAres(班门斧):  
              你斧头大哥的回答果然没错,的确是暗中调用了,因为按照大哥的程序,  
  输出为:  
  A:A()  
  B:B(int,int)   ,但是我现在还有疑惑,还望大家指导。  
   
   
   
                    class   A1  
  {  
  public   int   i,j;  
  public   A1()  
  {  
  Console.WriteLine("A:A()");    
  }  
  public   A1(int   i1,int   j1)  
  {  
  i=i1;  
  j=j1;  
  Console.WriteLine("A:A(int,int)---------{0},{1}",i,j);  
  }  
  public   A1(int   i1)  
  {  
  i=i1;  
  j=0;  
  Console.WriteLine("A:A(int)");  
  }  
  }  
   
  class   B1   :   A1  
  {  
                    //呵呵,俺把它注释调,反正他会继承父亲A1的无参数的构造函数的  
                    // public   B1()  
                    // {  
                    // Console.WriteLine("B:B()");  
                    // }  
  public     B1(int   i1,int   j1)//:base(i1,j1)  
  {  
  i=i1+100;  
  j=j1+199;  
  Console.WriteLine("B:B(int,int)----{0},{1}",i,j);  
  }  
   
  }  
  class   C1:B1  
  {  
  public   C1()  
  {  
  Console.WriteLine("C;C()");  
  }  
  public   C1(int   i1,int   j1)  
  {  
  Console.WriteLine("C;C(int   ,int)");  
  }  
   
  }  
                    public   class   test  
  {  
  public   static   void   Main()  
  {  
  C1   c=new   C1   (1,1);  
  Console.ReadLine();  
  }  
   
  public   test()  
  {  
  }  
  }  
  呵呵,程序竟然报错,说“重载B1方法未获得0参数”!!  
  B1不是可以继承A1的0参数构造函数吗?  
  是不是“直接基类”必须实现不带参数的构造函数啊?  
   
   
  继续往下面看:  
                      class   A1  
  {  
  public   int   i,j;  
                                      //我就是要想方设法的注释掉0参数构造函数,呵呵  
  //public   A1()  
  //{  
  // Console.WriteLine("A:A()");    
  //}  
  public   A1(int   i1,int   j1)  
  {  
  i=i1;  
  j=j1;  
  Console.WriteLine("A:A(int,int)---------{0},{0}",i,j);  
  }  
  public   A1(int   i1)  
  {  
  i=i1;  
  j=0;  
  Console.WriteLine("A:A(int)");  
  }  
  }  
   
  class   B1   :   A1  
  {  
                                        public     B1(int   i1,int   j1):base(i1,j1)  
  {  
  i=i1+100;  
  j=j1+199;  
  Console.WriteLine("B:B(int,int)----{0},{0}",i,j);  
  }  
   
  }  
   
                    public   class   test  
  {  
  public   static   void   Main()  
  {  
  B1   b   =   new   B1(1,1);  
                                                          Console.ReadLine();  
  }  
   
  public   test()  
  {  
  }  
  }  
  这回可没有出现错误了,因为我强制它调用基类的public   A1(int   i1,int   j1),  
  所以编译器就没有机会再“自做多情”的调用基类的0参数构造函数了  
   
   
  好,下面假设我有三个类:爷类,父类,孙类   (大家别笑啊)  
  1。如果我在爷类中没有实现0参数构造函数,父类和孙类就都甭想实现  
        0参数构造函数,并且父类和孙类的“非0参数构造函数”都必须“强制性”  
        的调用爷类的“非0参数构造函数”?????  
   
  2。如果我在爷类中实现了0参数构造函数,但是父类中没有实现,此刻,  
        孙类还是甭想实现0参数构造函数????  
        也就是说,我在类的设计中,必须实现类的0参数构造函数,否则的话,  
        它的后代永远没有机会实现0参数构造函数????0参数构造函数就会  
        "断子绝孙",它的后代,每实现一个“非0参数构造函数”,就必须  
        "强制性"调用父类的"非0参数构造函数",以此作为代价!!!?????  
         
  3。VCKBASE.COM   所说的"当从某个基类派生类的时候,基类de构造函数被暗中  
        拷贝到派生类的构造函数中去"  
                其实是说,如果派生类的构造函数没有“显式”的调用父类的“构造函数”,  
        则会发生这种“暗中拷贝”的问题,而一旦你“显式”的调用了父类的“构造函数”,  
          派生类是不会多此一举的?????????  
   
   
   
   
   
   
   
  Top

3 楼TheAres(班门斧)回复于 2003-08-01 22:32:01 得分 0

1,  
  >>呵呵,程序竟然报错,说“重载B1方法未获得0参数”!!  
   
  问题出在你注释的地方,你把没有任何参数的B的构造函数去了,对于从B继承的C来说就出问题了,因为它缺省要调用B的无参数的构造函数。  
   
   
   
  >>1。如果我在爷类中没有实现0参数构造函数,父类和孙类就都甭想实现  
  >>       0参数构造函数,并且父类和孙类的“非0参数构造函数”都必须“强制性”  
  >>       的调用爷类的“非0参数构造函数”?????  
   
   
  没有爷类的概念,记住只有父类的概念,一层一层的找。如果A->B,   B->C,例子如下,就可以。  
   
  //   cs_attribute_obsolete.cs  
  //   CS0619   expected  
  using   System;  
   
  class   A1  
  {  
  public   int   i,j;  
  // public   A1()  
  // {  
  // Console.WriteLine("A:A()");    
  // }  
  public   A1(int   i1,int   j1)  
  {  
  i=i1;  
  j=j1;  
  Console.WriteLine("A:A(int,int)---------{0},{1}",i,j);  
  }  
  public   A1(int   i1)  
  {  
  i=i1;  
  j=0;  
  Console.WriteLine("A:A(int)");  
  }  
  }  
   
  class   B1   :   A1  
  {  
   
  public     B1():base(0,0)  
  {  
   
  Console.WriteLine("B:B(int,int)----{0},{1}",i,j);  
  }  
   
  }  
  class   C1:B1  
  {  
  public   C1()  
  {  
  Console.WriteLine("C;C()");  
  }  
  public   C1(int   i1,int   j1)  
  {  
  Console.WriteLine("C;C(int   ,int)");  
  }  
   
  }  
  public   class   test  
  {  
  public   static   void   Main()  
  {  
  C1   c=new   C1   (1,1);  
  Console.ReadLine();  
  }  
   
  public   test()  
  {  
  }  
  }  
   
   
  Top

4 楼TheAres(班门斧)回复于 2003-08-01 22:35:38 得分 0

>>2。如果我在爷类中实现了0参数构造函数,但是父类中没有实现,此刻,  
        孙类还是甭想实现0参数构造函数????  
  不一定。见上面的例子。  
   
  >>       也就是说,我在类的设计中,必须实现类的0参数构造函数,否则的话,  
  >>       它的后代永远没有机会实现0参数构造函数????0参数构造函数就会  
  >>       "断子绝孙",它的后代,每实现一个“非0参数构造函数”,就必须  
  >>       "强制性"调用父类的"非0参数构造函数",以此作为代价!!!?????  
   
  父类没有,子类照样有。你只要指明白子类要调用拿一个父类构造函数就可以了,用base指定。  
   
  比如上面例子中的B1   和A1.  
   
   
  Top

5 楼TheAres(班门斧)回复于 2003-08-01 22:40:35 得分 0

>>3。VCKBASE.COM   所说的"当从某个基类派生类的时候,基类de构造函数被暗中  
  >>       拷贝到派生类的构造函数中去"  
  >>               其实是说,如果派生类的构造函数没有“显式”的调用父类的“构造函数”,  
  >>       则会发生这种“暗中拷贝”的问题,而一旦你“显式”的调用了父类的“构造函数”,  
  >>         派生类是不会多此一举的?????????  
   
   
  面上说的,就想你说的这样。估计实际编译的时候,可能就想文章上说的那样,是要拷贝一个函数去的。具体的编译步骤,我没有资料,也不是很熟。  
   
  估计这篇文章是用C++说的吧,最早C++的编译是先转换成c代码,然后编译的。你想想,C中完全没有OO的语法支持,肯定是产生了一个什么函数,来实现这一套的。  
   
  欢迎继续讨论,我把这个帖子转到C#去,看看大家有什么说法。  
   
   
   
   
  Top

6 楼yujianxueren(.)回复于 2003-08-02 09:44:11 得分 0

谢谢斑竹!Top

7 楼yujianxueren(.)回复于 2003-08-05 21:36:18 得分 0

最后一次up  
  要不,我明天结帐Top

相关问题

  • 构造函数
  • 构造函数
  • 构造函数??
  • 构造函数
  • 函数构造
  • @@@@@@ 构造函数 @@@@@
  • WebService构造函数
  • 构造函数和析构函数
  • 构造函数是内联函数吗?
  • 构造函数与析构函数

关键词

  • c++
  • 函数
  • 拷贝
  • 文件
  • 类
  • 构造
  • 参数构造
  • 调用
  • 孙类
  • 实现

得分解答快速导航

  • 帖主:yujianxueren
  • TheAres

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo