我在Unit1里面如下声明
  TA =class(TObject)
  private
    a:string;
    constructor create(s:string);
  end;
注意两点,(1)create我声明成private的(2)后面没有用overload指示字,这会让其覆盖TObject那个默认Create现在在Unit1中写下代码
A:=TA.Create('s');  //OK
A:=TA.Create;       //编译不通过
如上的情况我都能理解,问题在下面在Unit2中写下如下代码
A:=TA.Create;      //编译通过,OK
为什么会出现这种情况?

解决方案 »

  1.   

    你都知道在UNIT1里面申明在 private 里面了。那你在 unit2 中如何看到。TOBJECT的CREATE此时相对于UNIT2来说是不是唯一的构造函数
      

  2.   

    问题就在于TObject那个默认的Create:
    以我的理解,那个默认的Create已经被带参数的Create覆盖掉了,所以在Unit1中看不到是对的,但是在Unit2中怎么又出来了?反而能看到了?太奇怪了啊
      

  3.   

    那在UNIT2里面:
    A:=TA.Create('s');   这个能通过吗??
      

  4.   

    因为你写在了private中。对于UNI2来说,是看不到private中的方法的,它只是看到了TObject的Create方法。
      

  5.   

    其实说白了,就是 private 的问题,你将构造函数作为了TA所独有。那unit2 只能找父类的构造函数。
    因为对UNIT2来说,UNIT1中的构造函数是不可见的。
      

  6.   

    这就奇怪了的啊,Unit1看不到TObject的Create,我能理解。那到了Unit2中反而能看到了?那什么道理的吗?我就想搞清楚这个
      

  7.   

    那到了Unit2中反而能看到了?那什么道理的吗?我就想搞清楚这个
    ----------------------------------------------------
      Unit1中,将构造函数定义为private,那么,对于其他单元来说,你自己定义的constructor是不可见的.
      因此,在Unit2中,调用constructor的Create时,编译器没有在public中找到你定义的constructor,于是,它就会去调用父类中去寻找constructor,然后去调用,就是TObject.Create.
      

  8.   

    楼上的说法还是有些疑问:
    在Unit1中,编译器明显看不到默认的那个Create,编译都不会通过。但是到了Unit2中,难道编译器由于找不到合适的Create,就开了天眼,重新去基类中找到了那个默认的Create?这样的编译器行为岂不是很怪异?
    我一句A:=TA.Create;放在程序Unit2中编译能通过,Unit1中就编译通不过,实在让人沮丧。
    为什么在Unit1中编译器不去找找那个默认的Create呢?
      

  9.   

    TA在Unit1中声明了一个私有构造函数,没有Override指示字,表示你定义了一个新的构造函数并覆盖掉了TObject类中的默认的构造函数。当你在Unit1调用TA类的构造函数时,首先在本类中进行查找,发现了你自定义的构造函数,则直接调用,而不再到父类中进行查找。由于TA类中的构造函数被定义为私有,在Unit2中不可见,故到其父类TObject中查找构造函数并调用之。
      

  10.   

    编译器真如楼上的这说的吗?那这个编译器的行为就有些古怪:
    不用overload指示字,也就是明确我的Create会覆盖掉TObject的Create,编译器应该确定就是看不到基类的Create才对。而不是说看得到,但是我编译就是不让你通过,气死你。
    但是真到了Unit2里面,编译器突然又能看到基类的Create了,编译又放行了。。
    这样的逻辑应该是说不过去的呢,估计另有隐情,还求大牛继续解答。我觉得如果Unit2中A:=TA.Create编译能过,Unit1中没有道理编不过。要不就两个Unit都不支持,这才说得过去。
      

  11.   

      不要去钻牛角尖了。  为什么在Unit1中编译器不去找找那个默认的Create呢?  编译器有就近原则,当它找到第一个匹配的时候,它就不会再去找第二个。
      你可以做个测试,你在unit1中定义了一个函数Test,在unit2中同样定义了一个Test函数,unit1中引用unit2,那么如果你在unit1中调用Test,它只会找到unit1中的Test函数。如果unit1中没有定义Test函数,这时候它才会去其他单元找Test.
      差不多就是这个意思。
      它在TA中已经找到一个Create函数,那么,它就默认你调用的是这个Create,其他的一律不认。
      

  12.   

    楼上的例子是文件包含问题,这种处理是说得过去的,应为它必须有个规则,按照这个规则来就行了。但是恐怕这不能适应到对象模型,对象模型是个很严肃的问题,C++对象模型和Java对象模型我想决不会出现这个让人哭笑不得的现象出来。我一直认为Delphi的对象模型也是很先进的。但是对于它的对象模型居然会和pas文件的组织形式纠缠在一起耿耿于怀。我认为是败笔,阻止它成为一个一流的对象模型。
    另一个就是它的接口机制,有些混乱,和COM这种特定技术关联在一起,不是语言层面的一级特性,远不如Java的接口优雅,可惜可惜!
      

  13.   

    unit2中的表现是正常的,因为unit2中看不到TA的Public构造函数,
    编译器使用的是基类构造函数unit1中首先遵循的是友元的规则,
    因此private中的构造函数可见,而根据你前面所提到的“就近原则”,
    既然在类中找到了一个构造函数,自然就不会去找父类的方法。
    从这一点来说,unit1中的表现也是合理的。C++中同样有友元的概念,
    从对友元的实现来说,我倒认为Delphi比C++更好些
    因为C++中是通过关键字来标识友元的,
    类和类的友元允许分属不同的文件中,在文件比较多的情况下会很难维护,
    而Delphi把友元限定在同一个单元中,维护起来会更方便些至于接口机制,你的认识上更是有偏差,
    Delphi的接口机制是自COM而来,这是事实,
    自Delphi5以后,Delphi里有interface关键字,而且GUID也不是必须的,
    这足以说明接口已经成了Delphi语言的一部分,
    仔细研究一下,你会发现Delphi的接口与java没有什么两样
      

  14.   

    呵呵,所以我知道我估计只能算是个语言狂热主义者,并不是一个真正实战型的程序员。我只是太喜欢Delphi Pascal语言了。
      

  15.   

    楼上所有的人说的基本都8对,大家都没有提到一个概念——命名空间!你在Unit1中申明一个类TA,那么TA的命名空间为Unit1。即只有在Unit1中TA可见。对于Unit2,如果不引用Unit1,是压根什么都编译不过去的,因为你在Unit2使用了TA,而TA的命名空间在Unit2没有显式引用Unit1的情况下是不可能自动扩展到Unit2的。这是其一。另外,对于Unit2中的TA构造器可编译过去,并不是什么友类的原因。如果将A申明为TObject类型,那么直接使用TA构造器是肯定无法编译的。因为Delphi禁止向下引用。但如果将A申明为TA类型,则TA构造器语句是完全可以编译通过的。因为Delphi允许向上引用。所以,楼主请说明A的申明类型以及是否在Unit2中显式引用Unit1,因为这两个因素会导致编译错误(报告不同的错误信息)。最后,说一下Delphi的对象模型在这个例子中的应用。先说明一点,OOL类语言的OD(Object Model对象模型)基本都差不多,没有多大的区别。不用迷信哪个对象模型更好类似的无聊问题。众所周知,类在编辑期间申明,在PE加载后执行的时候(即运行期)分配VMT空间。对象同样是在编辑期申明,同样在运行期分配空间——栈上的4字节指针,堆上的对象实体空间。此实体仅仅包含属性等标志对象本身的数据,方法数据都是包含在堆上的VMT中。VMT与其说是一个表,不如说是一连贯的表,即[color=#0000FF]表链[/color]。子类的VMT中包含指向父类VMT的指针,在一个继承序列里,这种指向导致够成了上面所说的表链。在Unit1被Unit2引用,同时Unit2中使用TObject构造器的情况下,因为是向上引用,所以当在TA的VMT中找不到与调用匹配格式的构造器的时候,会自动顺延找到TA父类即TObject的VMT(通过TA VMT中指向TObject VMT的指针)中进行查找,当找到匹配格式的构造器的时候,即通过TObject VMT中记录的构造器地址(指针)直接调用TObject.Create。完成调用。
      

  16.   

    无论接口是否需要GUID,这些都不是重点。重点是接口和类的内存分配结构不一样。类需要heap上的VMT的支持,而接口也需要。两者的区别在于类的VMT形成的链结构中的每一个环节(即其他VMT。链结构的终点即端点是方法入口地址字段指向的方法代码段)都有后续指向环节(即其他VMT或代码段)。而接口则未必。如果接口没有实现类则接口VMT没有后续指向环节。另外一个类与接口的重要区别在于:接口的instance没有标志自身属性的内容。即接口instance必须指向其规范实现类的对象才有意义。COM仅仅是一种规范。现在流行的CLR中的多语言混合编程与其有类似之处理。
      

  17.   

    CSDN这烂地方,我再不回答问题就更烂了.
      

  18.   

    在unit1里,能看见私有的构造函数,这和友元是有关系的,
    要不解释不了A:=TA.Create('s');编译通过的原因命名空间只解释了“整个”TA类是否可见的问题,
    而对于在同一个单元里,可以看到TA类私有方法这个问题,
    如果不提友元,单单的一个命名空间很难让人信服unit2中A:=TA.Create;编译通过,说明unit2已经引用了unit1
    否则编译不可能通过的
      

  19.   

    GUID是COM接口机制的一大特征,
    凡是必须要有GUID的接口,或多或少都和COM有关
    早期的Delphi 3为支持COM规范所引入的接口,也必须要有GUID,
    这时的Delphi接口机制,算不上真正从语言层面提供接口机制,仅仅是作为一种“外挂”
    java接口用关键字定义、不需要从特定的根接口继承、不需要GUID,
    这种机制算是从语言层面提供的自Delphi 5以后的接口机制做了修改,也采用了java那种从语言层面提供支持的方式
    关于这一点李维在《inside vcl》第六章里也说了
    “Delphi的接口机制一开始是为了支持COM而加入Object Pascal的...
    到了Delphi 5之后接口机制已经成了object pascal的程序语言通用机制,并不只限于使用在COM之中,
    特别是Delphi for .net推出之后,...和COM再也没有依存关系了”
      

  20.   

    偶的天,友元和命名空间没有关系吗?在单元文件里面申明一个包含私有构造器的类,然后定义此类的一个对象,然后调用自身类的私有构造器,这个和友元有关系?这里和友元没有任何关系,仅和命名空间有关系!
    请楼上的搞清楚友元的含义在来做解释!另外,楼主的定义本身就有问题,构造器定义为私有的没有任何意义,纯粹是一种语言测试游戏。构造器一般都是虚方法,尤其在类继承链里面的前端更是如此。虚方法的目的是为了多态,即为了封装。最后,我提醒一点,单元引用可以全局引用和局部引用。如果写成A:=Unit1.TA.Create照样可以compiled。关于接口,无须多谈。请楼上的详细看看《COM本质论》。那里面阐述的非常详细。GUID的目的是为了防止命名空间的冲突,这里的命名空间和语言级的命名空间差不多含义。至于delphi因为何故引入接口,李维的书里面说的也未必准确,就我理解,接口除了支持MS COM规范之外,还有一个重要的用途就是实现模式。接口可以更宽泛的支持变化的封装即多态。这点要不虚方法,抽象类等多态支持途径要好很多。从内存分配来说,减少了内存占用量。从调用速度来看,减少了调用耗费时间。
    如果你对设计模式熟悉,可以看到GOF的23个设计模式里面大部分都使用了多态和接口来支持模式的构成技术。
      

  21.   

    程序2中访问不到private中的Create,则会调用它的父类(Tobject)的Create
      

  22.   

    constructor create(s:string);
    这并不能覆盖TObject.Create,
    你要写成constructor create;才可以。
    Delphi的类构造函数可以有多个,而且可以任意命名,也允许重载。
      

  23.   

    我有说过“友元和命名空间没有关系”这话?我一直强调的是,用友元来解释“同一个单元里,能够访问到类的私有方法”这一现象
    比用命名空间来解释要更准确事实上,object pascal里友元和单元、命名空间这些是紧密相关的
    “2.18.4 友类
    在C + +语言中有友类的概念(允许在其他类中访问私有数据和私有函数的类)。在C + +中这是通过关
    键字f r i e n d来实现的,严格地说,在Object Pascal中没有类似的关键字,但有类似的功能。凡是在相同
    单元声明的对象都认为是友类,都可以访问其他对象的私有成员。”
    这是《Delphi 5开发指南》里面的原话对于友元的定义,《C++Primer》里的原话“15.2友元 ...通过把函数或操作符声明为友元,一个类可以授予这个函数或操作符访问其非公有成员的权利”你的原话“在单元文件里面申明一个包含私有构造器的类,然后定义此类的一个对象,然后调用自身类的私有构造器”
    ——这难道不是友元?实在是搞不懂,明明可以互为补充的两个概念,怎么就成了不共戴天?
      

  24.   

    大头鸟说得对,Delphi的private相当于默认带友元,
    你要C++中的private效果,需要用strict private。
      

  25.   

    同一个单元里面建的类互为友元,所以Unit1里面能够看到TA的private里的create
      

  26.   

    “在单元文件里面申明一个包含私有构造器的类,然后定义此类的一个对象,然后调用自身类的私有构造器”这叫友元?偶的天,请sdzeng搞明白友元是什么再来做解释。楼主的这个问题和友元没有任何的关系,要有关系也是与命名空间有关系。在一个单元文件里面定义的两个独立类互为友元!请看清楚,是定义在同一个单元里面的两个类互相称为友元。友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元。我请Corm1和sdzeng明白一点:在一个单元文件里面定义一个类TA,然后在这个单元中定义这个类的一个对象A,然后调用TA的构造器创建A,即A.Create....。这不叫友元。友元是类级别的概念,说白了友元就是类。
      

  27.   

    “Delphi的private相当于默认带友元”这种说法实在不敢恭维!默认带友元?怎么个默认?怎么个带友元?友元在哪里?各位的基础我感觉也有点忒次了。友元是类的一种别称。在单元Unit1中同时申明TA和TB,此时TA和TB互相称为对方的友元——即TA是TB的友元,TB是TA的友元。
      

  28.   

    听说 FS复出了   我是来看热闹的  果然不负众望  那里有FS 那里就有官司打
      

  29.   

    偶的天,偶和人争居然能把AlphaX引出来,8错8错。你QQ多少,我的175322678,加我,我QQ上没你了。还有小伍的!镊子的就不加了.....呵呵.....
      

  30.   

    不好意思,早上回复了就出去了,
    FS这段时间还好?我少上论坛了,只是偶尔来问问题才上来。我倒是几次在google的搜索结果上看到FS的大名。
    我没QQ,不过我把我的email PS给你了, 
    AD也还好吧? 我也给你发了私信
      

  31.   

    要是LZ说清楚了,那个A对象是在TA里面还是外面,估计也不会引发后面的口水到该结贴的时候了
      

  32.   

    “基础忒次”的应该应该去看一下 http://dn.codegear.com/article/34324 关于strict private的说明。:)
      

  33.   

    Delphi中并没有定义“友元”这个概念,使用这个概念主要是对C++中友元概念的一种借用。
    所以“友元是类的一种别称”这种说法实在不敢恭维!:)
    在C++中除了在类中声明友元类之外,还可以有友元函数,允许在此函数中访问类的私有成员,而此函数是普通函数,不是任何类的成员。
      

  34.   

    懒球得和你们争了。最后回一帖。To DelphiGuy  先说一句,先看清楚想明白俺前面回的东西在发表评论也不晚。  我明确地说一下为什么说“友元是类的别称”!
      
      首先友元这个概念描述是类,不是类的实例对象。在同一个单元里面定义的两个独立的类互称为友元。在Unit1中定义类TA,然后定义TA的对象A,这个时候A不能叫做TA的友元。也根本没有这种叫法。所以友元是类这个级别的概念。同时友元是描述类的命名空间的一种概念,所以友元是类的一种别称。请楼上的看清楚想明白在考虑是否可以恭维。这里的别称范围很狭隘,必须是同一个单元中申明的不同类相互称为对方的友元。  此外,我觉得这里没有必要硬把C++扯进来。  关于你说的Strict Private的解释--“The private keyword actually creates a " friendship" relationship between classes in the same unit.  The strict private declaration creates a true private field, not viewable by any other class, not even classes in the same unit.”请你自己先看清楚我上面的回复!OK?  楼主在单元Unit1中声明TA,然后在单元Unit1中定义TA的对象A,我实在不明白为什么如此众多的人说和友元有关系?
      私有部分的方法对同一单元中的友元类可公开(但属性或字段不公开),但这里申明的是一个自身类的对象,根本没有友元类的存在。也请DelphiGuy看清楚前面的各项回复再来做答。To 大头鸟  “我在Unit1里面如下声明 
        TA   =class(TObject) 
        private 
            a:string; 
            constructor   create(s:string); 
        end; 
    注意两点,(1)create我声明成private的(2)后面没有用overload指示字,这会让其覆盖TObject那个默认Create 现在在Unit1中写下代码 
    A:=TA.Create('s');     //OK 
    A:=TA.Create;               //编译不通过 
    如上的情况我都能理解,问题在下面 
    ”从一开始楼主写的就是TA和A都在Unit1中。这里不存在友元,所以楼上的各位高手非要把这个解释和友元挂到一起实在不合适。  
      

  35.   

    又见DelphiGuy   ,我喜欢。
      

  36.   

    FrameSniper,我是认真看了你的发言,你的如下看法是有问题的:
    ====================================================
    楼主的这个问题和友元没有任何的关系,要有关系也是与命名空间有关系。在一个单元文件里面定义的两个独立类互为友元!请看清楚,是定义在同一个单元里面的两个类互相称为友元。友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元。
    ====================================================1. 楼主的问题确实与友元有关,根本原因是Delphi的private成员是所处单元的友元(注意是不仅仅是针对其他类,任何函数/过程都可以访问本单元中定义的类的私有成员),而不是命名空间的限制。
    2. “友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元”这种理解是错误的,在同一单元内照样存在友元关系,而且可以用strict private声明来取消。(当然这里说的“友元”是对类似C++友元概念的借用,因为Delphi中并没有定义“友元”这个术语,也没有相应的关键字。)对这两个问题都可以通过简单的代码来验证:
    {$APPTYPE CONSOLE}
    program test;type
      TClass1 = class
      private
        Data: integer;
        constructor Create(const Name: string);
      end;  TClass2 = class
      strict private
        constructor Create(const Name: string);
      end;var
      A: TClass1;
      B: TClass2;constructor TClass1.Create(const Name: string);
    begin
      writeln(Name);
    end;constructor TClass2.Create(const Name: string);
    begin
      writeln(Name);
    end;{ main }
    begin
      A := TClass1.Create('TClass1');
      A.Data := 10;                        // 由于private成员是本单元的友元,这是允许的
      writeln(A.Data);
      B := TClass2.Create('TClass2');      // 此行编译通不过,显然不是命名空间的原因
    end.
      

  37.   

    拜托CSDN的开发者,一个空格被扩展成三个的问题能不能解决一下呀?
      

  38.   

    1.   楼主的问题确实与友元有关,根本原因是Delphi的private成员是所处单元的友元(注意是不仅仅是针对其他类,任何函数/过程都可以访问本单元中定义的类的私有成员),而不是命名空间的限制。 
    2.   “友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元”这种理解是错误的,在同一单元内照样存在友元关系,而且可以用strict   private声明来取消。 先说下第一条:我不讨论楼住的问题了,楼住的问题是显而易见的。我说下友元和命名空间。首先我想说明一下命名空间。一个单元是一个命名空间,一个例程也是一个命名空间,同时一个类的可见性标记也可以限制命名空间。很多Delphi书籍都仅仅把命名空间和单元文件对应,很少有提到命名空间的广泛含义。
    如果你定义一个例程,不属于任何类,在内部定义一个局部变量,那么这个局部变量的命名空间就仅仅在这个例程的范围内。说白了命名空间就是描述编程对象的可使用性范围。这是其一!
    其二,命名空间必须是某个编程对象的命名空间,可以是一个类,一个对象,一个变量,也可以是一个表达式。所以,其二就是命名空间是描述编程对象的一个概念。对于友类概念,也是说明编程对象的可使用性范围的。因此,友类是命名空间的一种特殊约定,也可以说是一种特殊表现。这个看个人怎么理解。文无定法。编程也如此,一个概念从不同的角度理解肯定会看到不同的结果。DelphiGuy所说的Strict Private其实也是命名空间的一种外在约束。一个编程对象最后的可使用范围和编辑期文件的部署,编程对象的定义方式这两个因素有直接关联。其次,第二条:没有命名空间就没有友元概念——如果把命名空间比喻成一个苹果的价格,把编程对象比喻成一个苹果,那么友元就是这个苹果的附加包装。通过附加精美包装提高苹果的价格。没有价格概念,附加包装也就没有任何意义。这个道理很简单。你在单元Unit1中定义类TA和TB,如下.....
    TA=Class
    private
      FieldA:Integer;
    end;
    TB=Class
    private
      procedure ShowPrivateFieldOfTA(AField:Integer);
    end;
    .....
    A:=TA.Create;
    B:=(TB.Create).ShowPrivateFieldOfTA(A.FieldA);  //Compiled;
    .....TB的对象B使用TB的私有方法去显示TA的私有域的值。对于这个代码,在TA和TB申明后两个类的命名空间均为Unit1,即两个类的内容可以在Unit1中被其他编程对象所使用,但要受到可见性标识符的约束。但由于TA和TB互为友元,所以对于对方的私有内容也可以访问,完全不受Private的约束。即友元在命名空间的基础上扩展了编程对象(TA的私有域)的使用范围。很明显,友元是对命名空间的一种修饰,更何况语言这东西务必是先有命名空间概念其次再有友元概念。对于楼上所说的Strict Private说白了也是一种限制和约束或者说是约定。没有命名空间概念,友元这些概念也就没有意义,甚至对可见性标识符例如Private这些东西同样如此。最后我说下为什么先有命名空间后有其他约束性的修饰概念。无论面向过程还是面向对象还是现在炒得很火的面向方面。代码要编辑就存在代码的部署,代码的部署务必存在分离,通过什么分离?当然是文件啊,无论文件后缀是什么,这个要依赖于IDE Creator的喜好。代码分离后便于维护,但同样存在一个问题,被分离的存储代码的文件如何知道对方。因此出现了文件的引用。不引用则被分离的代码不可互知。正因为有为代码部署而出现的以文件方式分割代码以及为让文件相互可知而出现的文件引用,才出现了命名空间的概念。语言中很多概念自身是因为非语言的因素才引入的。如果一个项目所有的代码放入同一个文件,先不说好不好维护代码,至少语言中很多概念失去了其自身的意义。DelphiGuy所言的Strict Private中的Strict仅仅是编译器可理解的一个开关而已。见则完全限制可见性,不见则适当放开可见性。
      

  39.   

    我靠,FS你也精神太饱满啦,呵呵……Private Constructor的问题不知道被多少人折腾过了,真搞不懂这种问题有啥好折腾的,能折腾出啥来?有谁真的实际应用中玩Private Constructor?我觉得倒是想想怎么把Destroy给“Private化”,准确的说是让Destroy可以检测调用者是谁还有点实际意义。
      

  40.   

    FrameSniper,你确实能长篇大论,不过我也可以。:)“友元”的“元”是指什么?显然是元素、成员,而不是指类本身。
    所以,如果一个类允许从外部访问它的私有成员,那么它的这些私有成员就是外部访问者的“友元”。
    这些外部访问者,可以是其他类,也可以是普通函数/过程,二者对应友元类和友元函数(不只C++中存在友元函数,Delphi中也有,虽然没有明确定义,但是其使用方式是存在)。
    你的理解,“说白了友元就是类”、“友元是类的别称”等等,我认为是错误的,连适用主体都搞错了。
    你说的只能理解成“友类”,这与“友元”的概念是有所不同的,可以定义:如果A类的私有成员是B类的“友元”,那么A类是B类的“友类”。
    即便“友类”,也不是象你说的那样“在一个单元文件里面定义的两个独立类互为友元”,友类可以是单向的,在一个单元文件里面定义的两个独立类,如果A类有private成员,而B类只有strict private成员,那么只能说A类是B类的“友类”,反向则不成立。又或者两个类根本没有private和strict private成员,那么它们之间也谈不上友类关系了,本来就是对外部访问开放的,当然也就没有“友”和“非友”的区别了。正是你的这种理解偏差,导致一系列错误推论,你认为“友元”必定涉及两个类(或者多个类)之间的关系,而楼主的问题中只有一个类,所以与“友元”无关。
    错了,“友元”是类成员(被访问者),不是类本身,而且友元关系不仅对类,对函数/过程也可以存在(Pascal的主程序体就相当于C的main()函数)。对“命名空间”(namespace)的最通常解释是保证标识符(名字)不出现含糊的域(范围),它肯定是存在的,怎么能不存在呢?最简单的情况也可以理解成一个程序只有一个命名空间。
    因此你说的“没有命名空间就没有友元概念”是无的放矢、不着边际。可以说没有氧气人就不能活,但不能反向推理出所有的死亡都是缺氧造成的。
    而且你对“命名空间”的理解也存在问题,“命名空间”应该是定义域,而不是使用域,后者是不确定的,可以超出前者的范围。
    比如一个类的成员,不管是private、strict private、public,它的“命名空间”就是这个类的范围,能否从外部访问都不改变它的“命名空间”。我理解你说的是使用者看到的范围(scope),你uses A,就可以使用A中的常量、变量、函数等等,反之则不能。但是不管能不能,A中的常量、变量、函数的“命名空间”都是A,并没有改变。
    这个姑且不论,就按你的理解“命名空间就是描述编程对象的可使用性范围”,这种解释对楼主的问题来说就是离题太远、太空泛,好比你介绍一个人说“他是地球人”,基本上没有意义。
    语法规则的应用有一个最接近原则,也就是说最直接起作用的规则优先适用,不是你把更基本的规则搬出来它就更权威、更能说明问题。比如民法(中国目前还只有一部民法通则,相当于暂行民法)比婚姻法更基础,适用范围更大,但是因此说审理婚姻诉讼要优先适用民法,而不是婚姻法,那就只能是荒唐了。回到楼主的问题,从我前面举的例子代码可以看出,能否从外部访问类的私有成员,直接决定于是否存在友元关系,而不是类所处的命名空间。
    即便同一命名空间中的两个类,它们之间可以互为友类,也可以是单向友类,也可以不是友类,不管哪种情况,类本身,还有类的成员,其命名空间都没有发生变化,这个你不能否认吧。
      

  41.   

    再说一下,楼主只要把自己定义的私有方法create声明为overload,就可以在同一个单元内,既可使用自己的create方法,也可以使用基类的create方法。
      

  42.   

    呵呵,DelphiGuy,看来你是没学过编译原理了。算球了,爱怎么认为怎么认为吧,这种问题争球下去也没多大意思。照你说法,俺这快10年开发看来是白搞了.....
      

  43.   

    重新看一便 FrameSniper 的垃圾话,你就明白了!嘿嘿...
      

  44.   

    很抱歉,我确实学过编译原理,但可能不是您学的那种“编译原理”。
    而且这个问题与编译原理没有直接的关系,依据同样的编译原理,可以设计出语法规则差异甚大的语言来,你能说哪个的设计没有遵循编译原理?就问你一个问题:
    在A单元中使用B单元中的变量V,和在B或者其他单元中使用V相比,V的使用范围发生了变化,但是V的命名空间发生变化了吗?
    很明确,它仍然是B.V,没有变成A.V,也没有变成(A+B).V。
    如果你不认同这一点,那只能说对命名空间的理解上差别太大,各自保留意见吧。:)
      

  45.   

    也是。另外,由于使用中文描述的缘故,我前面对“友元”的解释可能会造成歧义,再试着说得更精确一些(咬文嚼字确实痛苦)。
    事实上,“友元”这个词在英文中只是friend,只有“友”的意思。
    如果
    A类对B类开放其私有或者保护的成员,则B类是A类的友元类(friend class),A类是B类的befriended class(由于很难找出一个中文词表达这个概念,所以只好使用“友类”这个词)。
    A类对C函数开放其私有或者保护的成员,则C函数是A类的友元函数(friend function)。
    我在前面没有写保护的成员,部分原因是由于楼主的问题是在讨论从类外部访问其私有成员,不过说明确实是不严谨的。:)
      

  46.   

    学过编译原理还用和你费这么多话?不知道你的哪个老师告诉命名空间和编译原理没有关系?如果你有Delphi技术手册,你可以看看其中的第三章的对象模型那块,看看对命名空间的解释是什么。我实在是懒的和你论了,照我以前的脾气早开始开骂了.....装B装到头了.....
      

  47.   

    To DelphiGuy:忘了回你这个问题了!
    “在A单元中使用B单元中的变量V,和在B或者其他单元中使用V相比,V的使用范围发生了变化,但是V的命名空间发生变化了吗? 
    很明确,它仍然是B.V,没有变成A.V,也没有变成(A+B).V。”当你在A中引用B,则V的命名空间自然会扩大。如果你要说不扩大,我也没办法。只能保留各自意见了。
    如果你要明白编译原理,我解释一下为什么命名空间会扩大。命名空间说白了就是编译器编译文件的时候记录的文件系统的树结构的结点而已。你上面所谈到的友元只不过是这个结点的一个引用而已。编译过程的语义分析阶段将建立一个申明类型和变量的表结构,此结构的一个字段用来记录命名空间的变化。之所以说是变化,是因为编译是一个过程,其间会关联多个文件。在编译结束后,此表结构的用来记录命名空间的字段内容被确定。但对于动态联遍的DLL以及一些COM应用不存在记录命名空间的字段。对应于Delphi对象模型,此字段对应于代码段中的部分代码。因为代码段中不存在什么表结构。如果你在A单元中定义了变量V,那么当编译器编译V的定义语句的时候会在相应字段中记录V的隶属单元(当然要看V的定义位置,即上下文),并依靠此字段记录内容来对后面要编译的内容进行确定。当编译单元B的时候,发现单元B引用了V,则将V的对应字段进行修改。修改的结果是同时表达A,B两个单元,说白了即文件名称。如果你要认为这个还不叫命名空间扩大,我也没什么可说的了.....整个命名空间的跟踪变化在编译期进行,不在链接期(先编译后链接)。你之前一再提到的友元无非也就是命名空间结点的一个引用而已(不是CPP中的引用,类似于一个类型指针)。至于你所说的Strict,更简单,编译器的一个开关而已。你上面的所有论调,大部分都是在和我强调概念,但实际的编译后台东西我看你并不明白。就像前面有位朋友说的:现实中没有人会定义私有的构造器,因为没有意义。为什么没有意义,因为私有不便多态,无法封装变化。其实编译与语法也是如此。很多语法在前台表现的各有差异,但在编译过程中很多部分都是同等对待。好了,最后你口口声声学过编译原理,懂面向对象,俺留个问题:
    重载和覆盖在面向对象语言中的对象模型是什么?在编译过程中又是如何被处理的呢?看清楚,我问的是对象模型是什么?在编译中如何被处理。即编译器看到Overload和Override如何处理对应代码?-----然懂就回答一点,不勉强。看你前面说的也“头头是道”的。这种问题应该很容易回答滴.....
      

  48.   

    呵呵...
    你也就剩下虚张声势的本事了。“当你在A中引用B,则V的命名空间自然会扩大。”这就是你对命名空间的理解???
    命名空间(namespace)或者叫名字空间、名称空间,是包含一套标识符的容器,在此内部,标识符可以通过名字来区分。
    命名空间是标识符的定义域(也可以包含声明),不是使用域。搞清楚了没?
    显然你把标识符的使用范围和它所在的命名空间混为一谈了。好好看看BDS 2006中的解释:
    ==============================================================
    Namespace and Package Overview
     
    A namespace is an element in a model that contains a set of named elements that can be identified by name.
     
    A project consists of one or more namespaces (or packages). A namespace and a package are almost synonyms: the term “namespace” is used for implementation projects, the term “package” is used for design projects.
     
    A namespace (or a package) is like a box where you put diagrams and model elements. Contents of a namespace (package) can be displayed on a special type of the Class diagram.
     
    Each project contains the default namespace (or package) just after its creation.
    ==============================================================没错,你“这快10年开发看来是白搞了”。
    你先是把友元关系理解成只能类对类,对楼主的问题想当然地以为“这里申明的是一个自身类的对象,根本没有友元类的存在”因此不存在友元关系。显然你连友元函数都不知道,类允许外部函数/过程访问它的私有/保护的成员那也是友元关系。楼主的例子能从类外部访问它的私有成员恰恰是友元函数在起作用(在Delphi中,一个类所在的单元中的所有函数/过程都是它的友元函数)。为了自圆其说,接着你又搞出一个标识符的命名空间随着使用它的位置不同而变化的概念,就更加滑稽了。
    标识符的命名空间居然随着使用它的位置不同而变化,那还要命名空间有什么用?设计命名空间的目的就是分离程序,消除名称冲突。
    “在A中引用B,则V的命名空间自然会扩大”?
    扩大到哪里?扩大到A?那岂不是又可能和A中的标识符名字冲突?
    你说使用B.V来区分,没错,那恰恰说明V的命名空间仍然是B!
    扩大的是使用者的看到的scope,而不是被使用者的命名空间。
    A引用B后,直接使用B中的变量V,并非V的命名空间扩大到了A,此V只是B.V的一个别名,V的命名空间仍然是B,并没有被添加到A中。
    不只Delphi的单元引用是这样,C++中使用using指示引用其他命名空间也是如此。
    你搞不清楚就先好好研究一下,不要东拉西扯,能解决问题吗?
    好比你是中国公民,被美国人请去转了一圈,你的国籍就变成美国了?还是双重国籍?
    笑话。本来对你还是客气的,点到为止,是你不知好歹,恼羞成怒还开骂了,这除了暴露出你的窘态,能有其他作用吗?:)
    你的编译原理问题留着自己玩吧,还是先把友元、命名空间之类的基本概念搞清楚再说,不要走都摇摇晃晃还吹嘘自己百米几秒几秒。
    好自为之,你的原话奉还:装B装到头了!
      

  49.   

    对我客气?真是笑话。
    可以说说我是怎么虚张声势吗。我上面讲的编译原理和对象模型哪里有问题可以直接指出来吗!阁下看样子不是对编译原理、对象模型很熟悉吗,那就帮俺FS解释一下我留下的那个问题吧,OK?
    不用一会引用这个书一会引用那个书的,自己亲自解释一下不是更有说服力吗.....我从一开始就说明这个问题不是友元的问题,只不过是半路杀出你这个自以为是的人非要在这里争此争彼而已。
    不知道阁下学的是什么编译原理,不用装了,装到这份上也不容易了。那问题就是直接提给你的,我就是想看看你到底有多大的本事哦.....“扩大到哪里?扩大到A?那岂不是又可能和A中的标识符名字冲突? 
    你说使用B.V来区分,没错,那恰恰说明V的命名空间仍然是B! 
    扩大的是使用者的看到的scope,而不是被使用者的命名空间。 
    A引用B后,直接使用B中的变量V,并非V的命名空间扩大到了A,此V只是B.V的一个别名,V的命名空间仍然是B,并没有被添加到A中。”——基本纯粹自编!啥叫别名阁下懂吗?“V的命名空间仍然是B,并没有被添加到A中”——学过编译原理吗?我仅是自学,你不是科班吗,呵呵,别装了.....你说错了一点,不是恼羞成怒,老子天生最看不惯的就是不懂装懂的人,球也不定还装的跟个B是的。不好意思骂人了,以前骂习惯了。已经很让你了.....阁下不是有能耐吗,那就劳驾回答一下俺提的那个问题吧?凭阁下的功力回答那个问题应该是很容易的喽.....不用我一提问题就躲得跟个蛋似的.....不好意思,俺没啥文化。静等答复!
      

  50.   

    此帖无需结。俺FS陪这个DelphiGuy装到底,8用跟我撤这撤那的,回答了俺的那问题俺就撤!
      

  51.   

    大家看看,装B的就是FrameSniper这种德性,被扒得光溜溜就连脸都不要了,死皮赖脸要别人回答你的什么问题,以为可以找回面子。
    这是楼主开的帖,你连楼主的问题都没搞明白,说个一个概念错一个,你还装什么装。就再免费教育你一次:
    很明显,你连namespace和namespace member's scope都分不清,还嘴硬。
    在namespace中定义或者声明一个identifier,它就成为此namespace中的一个member,它的默认scope就是包含它的namespace,它的潜在scope是所有引用包含它的namespace的区域。
    注意此scope是指标识符可见、或者被使用的区域,不是它的命名空间!
    这些基本概念,几乎在各种语言的标准中都有,没有什么差别,就随便给你摘一段:
     3.3  Declarative regions and scopes                      [basic.scope]1 Every  name  is  introduced  in  some portion of program text called a
      declarative region, which is the largest part of the program in  which
      that  name  is  valid,  that  is, in which that name may be used as an
      unqualified name to refer to the same entity.  In general,  each  par-
      ticular  name is valid only within some possibly discontiguous portion
      of program text called its scope.  
    看清楚没有?一个name的scope是它可以被使用的区域。
    另外,在C++标准中明确说明“A using-directive does not add any members to the declarative region in which it appears.”
    你这个笑料还搞出什么“当你在A中引用B,则V的命名空间自然会扩大”,真是个大棒槌。
    扩大的是使用者看到的scope,或者说被使用者可被用于的scope,不是被使用者的namespace!傻了吧,还嚣张吗?
    你还是先把一些计算机语言的基本概念搞清楚再出来卖弄也不迟,就你这浆糊脑子,够你再学个十年的。
    你看看你在这个帖子里的表现,不知道自己吃几碗干饭,NB哄哄,鼻孔朝天,进来就咋咋呼呼,打击这个,打击那个。别说你那二把刀水平,你就真是高手,至于这么嚣张吗?
    看在这是一个技术帖,而且快过年的份上,一直给你留着面子,容忍你的无礼。
    可你倒好,给脸不要脸,连续说错基本概念,不但不道歉,还现出一个泼皮牛二的嘴脸,东拉西扯,胡搅蛮缠,不但无知,更加无耻。
    你现在的的表现就象考试不及格被家长暴打的顽童,鬼哭狼嚎还嘴硬:“我出个题你能考及格吗!你先回答我的问题,否则你就不及格...”
    哈哈哈...
    真TMD丢人。正是:
    面壁十年图破壁,
    破壁空留南郭名;
    大师不甘贻笑众,
    再练廿载亦蒙羞。
      

  52.   

    编译原理“大师”,怎么不出来了?玩不起了?我还没给你最后一击呢。先让大家看看,这个“大师”,其水平到底如何,引用他的经典言论如下:43楼:但这里申明的是一个自身类的对象,根本没有友元类的存在。
    =============================================================
    评论:您知道友元函数吗?
    解释:友元关系不仅仅是类对类,类对函数也可以,一个类允许外部函数访问它的私有、保护的成员,就是它的友元函数。
    在Delphi中,一个类所在单元的所有函数/过程都是它的友元函数(Pascal的主程序体也是一个过程,相当于C的main())。61楼:当你在A中引用B,则V的命名空间自然会扩大。
    =============================================================
    评论:您搞得清标识符的命名空间和标识符的作用域的区别吗?
    解释:简单地说,命名空间是包含若干标识符的容器,在此空间之内,每个标识符具有唯一的名字。设计命名空间的主要目的就是避免名字冲突。当在命名空间中定义/声明一个标识符后,它就成为此命名空间的成员,这种关系是明确的,不会随着它被使用的区域不同而改变。
    而标识符的作用域,就是它可被看到,或者被使用的区域。标识符的作用域包含它的命名空间,但不限于此,是不确定的,随着它被使用的区域而变化。当在A单元中使用B单元的变量V,则V的作用域扩大到A,但是它的命名空间仍然是B(很明确,它是B.V,没有变成A.V)。
    举个类似的例子:命名空间就相当于国籍,一个中国公民不论去世界上任何地方,他的国籍仍然是中国,而他出现的位置则可以发生变化(作用域)。
    看到了吧,还真是“基础忒次”,还真是“不懂装懂”,怎么就这么有自知之明呢!
    就是这么个基本概念都一脑子浆糊的二五眼,还猖狂得不得了,在这个帖子里一出现就上蹿下跳,看人都鼻孔朝天,七个不服、八个不忿,打击这个、打击那个,你说说别人招你惹你了?
    “大师”,你那点水平,从你在28楼的发言就看得一清二楚了。我一直对你引而不发,容忍你的无礼,给你留着面子,让你有个全身而退的机会。(不承认?那就好好看看在你60楼彻底撒泼之前,我说过过分的话没有?)
    一是因为这是一个技术帖,不想引发不相关的争论。
    二是因为快过年了,不想伤你,把你搞得灰头土脸的没什么意思。
    是你不知死活,一直咬我,我不得不对你痛下杀手。
    现在你爽了吗?吸取教训吧。:)
      

  53.   

    "当在命名空间中定义/声明一个标识符后,它就成为此命名空间的成员,这种关系是明确的,不会随着它被使用的区域不同而改变。"——纯粹放屁。楼上的,我请你去认真看看编译原理在来这里做解答。误了自己不要紧,本身就是个死要面子的东西,不用跑到这里来误人子弟了,OK?呵呵,前面不是很含蓄吗,怎么到了最后变得跟个疯狗是的,把损人的本事都拿出来了吧?不用损我了,损我只能让我感觉你压根就是个只知道皮毛,不知道内涵的初学者.....也不用拿那么多概念来压我!压制我的最好方法我已经在上面和你说过了,正确地回答我的那两个问题吧,从面向对象的角度和编译的角度来回答,那才叫本事,不用像狗一样乱吠了。“别以为这就算完了,这仅仅是开始。 
    你可以选择在这个帖子里充当的角色,谦虚的旁观者,积极的参与者,或者一个泼皮无赖。 
    你已经作出了选择,就要为你的选择付出代价。 
    你可以决定如何开始,但是如何结束,那可由不得你了。:) 
    ”——偶不知道如何形容你了,整个一个没娘的娃娃!是不是以为俺躲着你呢?太自负了吧.....快回去好好翻翻书来回答我那两个问题吧,不用每天闷着心思在这里搅尽脑汁地来损人了,想骂就骂吧,偶FS不会介意的,但要骂就骂的像个男人点,别跟个青楼的娘们是的扭扭捏捏,又作诗又祝你哥我新年快乐什么的,整个一娘们德行。最后和你说一句,快回答我的问题吧,回答出来俺FS自动退出,认可你的皮毛理论,不回答我们就一直骂下去。忘了告诉你了,前两天收拾家没时间上来.....不要以为你爷爷躲着你个小B孩.....鼠年到了,俺不祝你快乐了,只因为不想像你跟个娘们一样在这里装B.....过了大年,FS爷爷陪你继续在这里演戏.....OK?煞笔大白痴.....呵呵.....
      

  54.   

    不愧是个棒槌!还真是“基础忒次”、“不懂装懂”!
    就这么一张被大家的目光烤成死狗的贱脸,还要嘴硬。
    本来看你这被修理得狼狈不堪的可怜样,还想放你一马,可你倒好,给脸不要脸,还趁着我不在的这几天放个屁、吹个牛,小小的自慰一翻,以为可以找回你那一钱不值的面子。真是个TMD笑料!那也只好把你一棒子打死,让你彻底没脸见人。你要是搞不懂命名空间(namespace)和作用域(scope)的概念,就花点时间好好研究一下,而不是一再跳出来胡说八道、丢人现眼!
    技术问题,是你死缠烂打,装傻充楞就可以任意篡改、混淆视听的吗?
    就你这种基本概念都搞不明白的浆糊脑袋,你还以为喷“编译原理”四个字就可以在我面前耍宝?你不是个笑料还能是什么?看来不用编译原理狠扇你几个大嘴巴你就皮子痒痒!
    你随便找译本《编译原理》,看看其中的符号表部分写的是什么?
    比如经典的《编译原理及实践》第六章 6.3.3 作用域规则和块结构 讲的是什么???
    是“作用域”还是“命名空间”?!
    大嘴巴狠抽你这个给脸不要脸的贱货!看你再嘴硬。
    你这个囔糠的夯货!犯贱的呆子!你一再被我牵着在大家面前溜,还不长点眼色,你是不是根本就不知道这世界上还有羞耻两个字?我就再最后教你一次,什么是作用域,什么是命名空间。
    随便摘一点msdn上的资料:
    http://msdn2.microsoft.com/en-us/library/b7kfh662.aspx
    Visual C++ Language Reference
    Scope
    C++ names can be used only in certain regions of a program. This area is called the "scope" of the name.  http://msdn2.microsoft.com/en-us/library/5cb46ksf(VS.80).aspx
    Visual C++ Language Reference
    Namespaces (C++)
    A namespace is a declarative region that attaches an additional identifier to any names declared inside it. 睁大你的狗眼看好了!两者是一回事吗?FrameSniper,你为什么落到被反复羞辱,欲罢不能的地步?你觉得委屈,觉得不甘心就好好反省一下你在这个帖子里的表现,是你的嚣张+无知+无耻的丑恶嘴脸让你自我毁灭,不是别人和你过不去,这是你自找的!
      

  55.   

    好好装吧,不用和偶在这里谈什么命名空间这些东西了。我说了,有点本事就回答下我的问题。不用和我撤东撤西的什么作用域和命名空间了.....我懒的骂你了,偶FS在CSDN骂人只骂两种人,一种是很惯的人,那叫开玩笑,一种是爱装B的人,类似你这种的,那叫侮辱和嘲笑.....对于你这种人装B货,我看我是基本不用骂了,至于你爱骂就好好骂吧,越到后面越可以看出你前后差别有多大,前面还装的想个B是的,后面基本就是一个B了.....别J8和老子废话了,不用拿什么编译原理的书来压我。孰对孰错懂的人一看就明白,可惜CSDN这地方大部分都是初学者,所以类似你这种B货可以随便侃而不露马脚.....我等着你回答俺的问题,B货!
      

  56.   

    我在Unit1里面如下声明 
        TA   =class(TObject) 
        private 
            a:string; 
            constructor   create(s:string); 
        end; 
    注意两点,(1)create我声明成private的(2)后面没有用overload指示字,这会让其覆盖TObject那个默认Create 现在在Unit1中写下代码 
    A:=TA.Create('s');     //OK 
    A:=TA.Create;               //编译不通过 
    如上的情况我都能理解,问题在下面 在Unit2中写下如下代码 
    A:=TA.Create;             //编译通过,OK 
    为什么会出现这种情况?
    -----------------------------------------------------------------------------------------
      搂主 A:=TA.Create('s');     //OK 
          A:=TA.Create;               //编译不通过  真能通过吗?
    var
      a: string;a := ta.create(''); 能通过?
      

  57.   

    FrameSniper,你嚎啊,继续嚎!我看你能嚎出个“自主创新”的“编译原理”来?!
    你这种笑料,又“不谈命名空间和作用域”了?
    哈 哈 哈 哈 哈 ...
    那你前面一直在放屁呀?
    落慌而逃还要摆个POSE,你就丢人吧你。
    回答你的问题?你还是先把基本概念搞清楚,先把楼主的问题搞清楚!
    你这种转移话题的遮丑伎俩,有用吗???
    你你这种一脑子浆糊、一肚子稻草的废柴,还有脸出来喷什么“十年研发”?!你这十年是吃屎长大的呀?
    你已经倒了,还做梦挽回你那早就被剥了皮的“面子”呀,省省吧。正是:也曾上山寻虎,
    亦想下海擒龙;
    搬梯扶摇觅月宫,
    咕咚。欲学慧能讲法,
    更慕达摩传经;
    奈何周公早收工,
    轰隆!
      

  58.   

    FrameSniper,
    再顺便教育你一下:你那白痴问题在C++标准化文档中解释得很清楚,也就你这种废柴以为可以搬出来忽悠一下。
    建议你这种知道自己“基础忒次”、“不懂装懂”的,最好找一下C++STANDARD-ISOIEC14882-1998看一看,不要再连作用域和命名空间都分不清了!
    你看你这丢人现眼的德性,以嚣张+虚张声势开始,以被修理得体无完肤+丑态百出而落慌而逃。
    你落慌而逃还要摆个POSE,还整出一个“孰对孰错懂的人一看就明白,可惜CSDN这地方大部分都是初学者,所以类似你这种B货可以随便侃而不露马脚”,还真是有自知之明啊,你有这自知之明早干什么去了?非要吃了苦头才知道后悔吗?!
    可惜你这自知之明还是差了一点:你没能“不露马脚”,你才两个帖就被扒得光溜溜,成了彻头彻尾的笑料。你不是还要阿Q吗?对不起,连这点面子我也不给你,非把你玩得死翘翘不可。
    这么说吧:
    咱们两个,谁不懂装懂,连基本概念都没搞清楚就出来虚张声势,打击这个,打击那个,谁就TMD不是人养的,全家遭雷劈!
    怎么样?我看你再嘴硬???
    哈 哈 哈 哈 哈 ...
    给脸不要脸的东西,你趁早买块豆腐一头撞死算了。
      

  59.   

    来来来,棒槌大师,快出来给大家继续喷你的“编译原理”和“命名空间”哪?还不好意思呀?你不是连脸都不要了吗?怕什么!你有一句话说对了,我就是要羞辱你,不过这是你自找的,凡是把这个帖子从头到尾看一遍的人,都会得出这样的结论,你纯粹是贱脸找扇,咎由自取,活该!你看看你这名字起的,FrameSniper,不就是“犯傻”吗?还真是自证其身!
    既然你这么爱犯傻,那就请大家再好好欣赏一下你的“精彩表演”:19楼:CSDN这烂地方,我再不回答问题就更烂了.
    22楼:这里和友元没有任何关系,仅和命名空间有关系! 
    28楼:友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元。
    29楼:各位的基础我感觉也有点忒次了。友元是类的一种别称。
    43楼:从一开始楼主写的就是TA和A都在Unit1中。这里不存在友元,所以楼上的各位高手非要把这个解释和友元挂到一起实在不合适。 
    61楼:当你在A中引用B,则V的命名空间自然会扩大。
    64楼:学过编译原理吗?
    68楼:编译的东西和对象模型的东西我自认很清楚,
    74楼:楼上的,我请你去认真看看编译原理在来这里做解答。误了自己不要紧,本身就是个死要面子的东西,不用跑到这里来误人子弟了,OK? 
    76楼:不用和偶在这里谈什么命名空间这些东西了。我说了,有点本事就回答下我的问题。不用和我撤东撤西的什么作用域和命名空间了.....别J8和老子废话了,不用拿什么编译原理的书来压我。大家看到了吧,这么个笑料东西,还嚣张得不得了。可惜一上来就闹了个大笑话,连友元关系都没搞明白,友元函数都不知道,就整出一个“这里和友元没有任何关系”,摔了个嘴啃泥。
    等我告诉他类和函数也可以构成友元关系(友元函数)之后,为了遮丑,他又死咬住“命名空间”不放,开始喷“友元这个概念是因为存在命名空间这个概念才存在的。没有命名空间就谈不上友元。”
    然后我又告诉他,命名空间(namespace)和作用域(scope)不是一个概念,标识符的作用域会随着它的使用区域不同而变化,但是标识符的命名空间不会随之改变。他继续嘴硬,还虚张声势,扯出“编译原理”来了。
    然后我又告诉他,《编译原理》上讲的是作用域,不是命名空间。他就只剩下摆POSE了,作用域、命名空间、编译原理都不谈了。哇哈哈哈哈... 虚张声势->狼狈不堪->生搬硬套->恼羞成怒->丑态百出->落慌而逃,就是这位FrameSniper(本名范傻)的生动写照。
      

  60.   

    delphiguy一向比较冲动,而且最喜欢在技术讨论比较深入时突然插一杆子,让大家不欢而散。
      

  61.   

    delphiguy一向比较冲动,而且最喜欢在技术讨论比较深入时突然插一杆子,让大家不欢而散
      

  62.   

    sxqwhxq和liangpei2008,两位,发表意见之前最好把此帖从头到尾看一遍,你们看看这个笑料在60楼彻底撒泼之前,我对他说过一句过分的话没有?其实他在60楼之前就有过多次无礼言论,我一直都在容忍他。
    我不想标榜自己的人品如何如何好,但是至少一个原则还坚持得很好:尽量与人为善,不主动攻击别人。但是如果有人先攻击我,尤其是象范傻FrameSniper这种无知还嚣张得不知道自己吃几碗干饭的货色,那对不起,我就非把他狠狠修理,彻底踩死不可。象范傻FrameSniper这种货色实在令人费解,搞不懂他到底嚣张个什么劲?吹嘘什么“十年研发”,居然连友元函数都不知道,连标识符的作用域和命名空间都分不清,吹嘘“编译的东西自认很清楚”,可是连《编译原理》上写的是作用域还是命名空间都弄不明白。这种说一个概念错一个概念的钝胎,还嚣张得上蹿下跳、摇头摆尾,打击这个、打击那个,这种败类,我不修理他,对得起天理吗?对得起在这个帖子里被他无端攻击的人吗?:)
      

  63.   

    呵呵,偶FS也就是实在没事情才上来看看和你玩玩,看来你还真有闲情逸致啊!我先承认自己是你所谓的废柴,然后接下来恭听你这位非废柴的大论,回答我的问题吧,不用拿什么书籍来压偶了,OK?你这种弄文青年惯用的把势偶FS见的多了。快点回答我的问题吧,小东西.....
    讽刺偶有什么用?能满足你的脆弱的心理吗?呵呵.....
    前面还像个人,突然被我一句骂激的想个疯狗一样,本质乎?正常的人是不会有你这种反差的.....
    等着你回答问题。
      

  64.   

    上帝 看了2小时37分钟才看完 总体来说 FrameSniper说的更靠谱 DelphiGuy建议你详细看看编译方面的内容(个人感觉你对编译这些基本理论知之更少) 命名空间和作用域表面上看似乎没什么关系 但在编译实现内部联系很紧密 对于友类 FrameSniper讲解的内容过于注重概念 但基本是对的
    不过提一点 FrameSniper骂人在先不对 DelphiGuy紧追不舍也不对(你谈的概念过于表面化 内部机理看来不是很明白清楚)-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
    本人现在研究方向为编译原理 目前就读华东理工大学研究生二年纪
    不敢说对编译原理很熟悉 但“研究”了这两年多 多少懂一点 嘿嘿
    两位不用继续争论 FrameSniper应该学会用简单的语言阐述理论
    DelphiGuy应该透过表面看本质
      

  65.   

    Ho Ho ... 马甲都上来了。
    看看这位的“简历”,真够简的:
    http://hi.csdn.net/compilerdev
    所在行业:未填写
    社区头衔:
    个人简介马上查看他的简历
    未填写
    个人专长
    未填写
    专家分: 目前总共有0分 马上查看他的帖子博客:目前总共有0条评论 马上阅读他的博客
    访问量:0 排名: 20000名之外 文章数:0条
    资源:目前总共有0分 马上查看他的资源
    上载资源数量:0 下载资源数量:0
    空间统计
    共有0人访问过此空间,排名574681 位
    发表文章:0篇, 发表帖子:2个; 资源:0个注意这“发表帖子:2个”是CSDN统计的一个BUG,点击右边的“发表帖子:2篇”查看,就只有这一篇回复(到目前2008-02-20 20:52为止)。
    分明就是个刚注册就直扑过来的托。哈哈哈哈哈...
    范傻,你呀,都可悲到这种程度了!让人说你什么是好啊。你再狡辩也没用,你连友元函数都不知道,上来就整出个“楼主的例子中没有友元关系”,那能叫“基本正确”???再“透过现象看本质”,命名空间和作用域也不是同样的概念,标识符的明明空间也不会随着它的使用区域不同而变化。至于两者的区别,我在前面的帖子里已经讲过多次了。范傻,你就省省吧。你也就剩下阿Q那点本事了,你以为虚张声势+托就有用啊???能挽回你那早就被扇烂的脸哪???完全脱离现实的幻想!你不但可悲,精神都不正常了。
    对你有一言相劝:有病治病!不要丢人误己!
      

  66.   

    分明就是个刚注册就直扑过来的托? 不说什么了 觉得有意思来“劝架”奉劝DelphiGuy这位朋友莫要太自以为是了 你的讲解过于肤浅 至少我认为你很多深入一些的东西不是很清楚 请谦虚接受别人的意见 你说的没错 我的ID才注册不到几天 如果你认为是托那就是吧
      

  67.   

    范傻,你还在垂死挣扎呀?有用吗?你自己都被修理得满地找牙,“命名空间”、“编译原理”也不敢吹了,还以为整个马甲出来就能把你这条死狗吹成“雄狮”???
    你早就倒了!还做梦想翻身哪?还玩这么拙劣的马甲手段(好好好,不是你的马甲,是贱脸找抽的马甲、是生孩子没P眼的马甲、是全家遭雷劈的马甲... 哈哈哈哈哈,你满意了吗)?你的精神状态显然已经很不正常了。
    就你这种说一个概念错一个概念的笑料嘴脸,你的那点脸早在28楼就丢没了,还不知死活、没脸没皮,一再跳出来装模作样、虚张声势,你还有没有点羞耻心和自我认知能力呀?你一次次被我牵出来溜给大家看觉得很爽吗?!
    从生物学来看,你的特征就是神经系统发育不全,额叶呈原始形态。在心理学上,你就是典型的认知型人格障碍,对自我和外部世界的认识完全脱离现实,有明显的妄想症状。什么是“太自以为是”、“过于肤浅”、很多深入一些的东西不是很清楚”呢?
    只要把如下几个和楼主的问题相关的问题回答一下就很清楚了:
    1. 楼主的例子里到底有没有友元关系?
    2. 作用域和命名空间是一回事吗?
    3. 《编译原理》中符号表部分讲的是作用域还是命名空间?我要看看你这个整出“楼主的例子中没有友元关系”、“友元是类的一种别称”、“命名空间就是描述编程对象的可使用性范围”、“当你在A中引用B,则V的命名空间自然会扩大”...诸如此类笑料的人是如何“不自以为是”、“不肤浅”、很多深入一些的东西很清楚”的???
    就你这种嚣张+无知+无耻的德性,天都亮了N次了,你还做梦哪?技术上的正确与否,那是有客观标准的,是你胡说八道、胡搅蛮缠就能篡改的吗?别说你整一个马甲(还如此拙劣),你就是整1000个马甲上来发帖,你的无知还是无知,你出了丑还是出了丑,能改变吗?!
    早在2006年,CSDN上就有人这么评价你“FS只是个没文化没素质的盲流而已”,此评价只能说:精辟!
      

  68.   

    不要咬着人不放了,都春节前的帖子了,今天上班实在无聊一上来居然在第一个就看见了,这种理论性太强的东西我实在没兴趣,做程序员嘛,就是为了混口饭吃,能写出合格的程序,能快速的进行维护就够了。大家在这么小一个问题上争论那么多已经失去意义了。
    DelphiGuy确实有才,这个不得不佩服,技术上你和FS到底谁对谁错我也没能力判别,不过你不是说这是技术贴,也不想骂人吗?你讽刺了将近有10个帖子了,还顺带把一个新人给讽刺了,虽然你骂人从来不带脏字吧,但是如果那个新人真的不是马甲呢?你这么一来不是也把CSDN的牌子砸了吗?不是也把自己的牌子给砸了吗?就好比说你被疯狗咬了一口,结果你反过头来把那狗一口咬到死,这不是比疯狗还疯狗了吗?
    保持点风度吧,你已经神经过敏了,好像所有出来劝架的或者说FS一句好话的人就都是他的马甲,都是要给FS翻身似的,殊不知你在发挥你的口才展示你的精明的时候,已经把你的风度丢的一干二净,慢慢沦为你自己骂的那一类人了。
      

  69.   

    不知道一会DelphiGuy是不是也会说我是马甲呢?不用你费心,我把我的某些资料数据粘贴出来给你看吧:
    专家分: 目前总共有137分
    Delphi:109分 扩充话题:13分 MS-SQL Server:10分 我想就算是马甲,也不容易在短时间攒这个分数吧?另外,你可以看看我的空间,
    共发表文章:0篇,发表帖子:84篇;资源:0个;网摘:0个
    这些帖子是从07年6月到现在发的,FS的预见性是不是太强了一点啊?PS:DelphiGuy,我不是想跟你争什么,说实话,我还是满佩服你的,因为你讨论的这些问题我都是不怎么懂的,而且你就算骂人也从来不带脏字,这不是一般人能做到的。但是我看不惯的就是你到现在还咬着人不放,慢慢的还发展到见谁咬谁,这实在是让我这个本来欣赏你的人很失望。希望你悬崖勒马,就算以前别人是疯狗,我也不希望你打了疯狗之后自己又成了疯狗。况且别人也不一定是疯狗,只不过你们意见不合而已,不至于一棍子把人打死啊。
      

  70.   

    对了,还有一种可能,我还忘了,DelphiGuy,你还可以认为我是托的,这个我还真没办法去辩解,毕竟就算我把我身份证拍这儿对着毛主席发誓你也不会信,算了,你要是那么认为我就不说什么了,我只想跟你说一句,人生的路很长,千万不要钻牛角尖,好自为之吧。
      

  71.   

    Ho Ho ...
    这位,你是不是托我并不关心,也不做判断。但是那位肯定是马甲,你也不至于看不出来吧。我修理这个范傻,不是因为他说错了技术上的东西,他错了与我有什么关系?完全无关紧要的。根本原因是他的嚣张+无知+无耻的态度,凡是把这个帖子从头到尾看一遍的人都会承认,他落到这种下场纯粹是他自找的。
    只要他还还敢跳出来嚎叫,打狗行动就要继续进行。在这CSDN上被我踢死的,范傻不过是平淡无奇的“之一”,他不是第一个,也不会是最后一个,无知还嚣张得上蹿下跳、出言不逊的人多得是,就象苍蝇,打也打不完。:)
      

  72.   

    对咯,你也知道这些人是打不完的,CSDN就像咱们这个社会,总是有那么多自以为是,牛皮哄哄,嚣张的上蹿下跳的人,与其浪费精力和他们咬来咬去,不如睁一只眼闭一只眼,任凭风吹雨打,我自闲庭信步。大家都是出来混饭吃的,干好自己的事情,养活老婆孩子,比什么都强。
      

  73.   

    DelphiGuy说白你就是个疯狗.....现在叫的越来越像了.....你FS叔叔实在是有赚钱的买卖要做,要不陪你玩玩。楼上说的没错,养活好老婆孩子比什么都强.....煞笔货一个,老子等球了你这么长时间了,快点回答老子的问题吧,别在这里跟个B是的一会弄文一会弄B嘴的。你FS爷爷一个礼拜以后来这里看你的答案,别让你大爷失望哦!
      

  74.   

    不要脸的贱东西!还在这象疯狗一样嚎叫,你以为挽回得你的面子吗???
    你的面子早就没了!你也早就成了一条被打断脊梁的赖皮狗!还不知死活,你到底知不知道世界上还有羞耻二字呀?要回答问题?你还是先回答一下和楼主相关的问题:
    1. 楼主的例子里到底有没有友元关系?
    2. 作用域和命名空间是一回事吗?
    3. 《编译原理》中符号表部分讲的是作用域还是命名空间?你不是彻底不要脸了吗?好!你出来嚎一次,我就在这剥一次你的皮!看看你造出的
    “楼主的例子中没有友元关系”、“友元是类的一种别称”、“命名空间就是描述编程对象的可使用性范围”、“当你在A中引用B,则V的命名空间自然会扩大”...诸如此类的笑料。就你这种货色,你这“十年研发”还真是白搞了,你趁早把自己捏巴捏巴钻马桶里算了(记得冲水)。就你这种一脑子浆糊、一肚子稻草的东西,还在我面前卖弄你的猴屁股、吹什么“编译原理”?整个一个笑料!
    你还喷什么你的问题?能救得了你的命吗?早在前面的帖子里就教育过你:
    你那白痴问题在C++标准化文档中解释得很清楚,也就你这种废柴以为可以搬出来忽悠一下。
    建议你这种知道自己“基础忒次”、“不懂装懂”的,最好找一下C++STANDARD-ISOIEC14882-1998看一看,不要再连作用域和命名空间都分不清了! 
    你要看不懂的话就再教教你,在
    3.4 Name lookup
    10.3 Virtual functions
    13.3 Overload resolution
    部分有详细的解释,还需要给你抄出来吗?白痴!你以为我不理你的茬就是不会?你不就是想转移话题遮丑吗?还玩这种顽童伎俩?做梦!
    你看看你这种丢人现眼、垂死挣扎、丑态百出的表现,还真是活脱脱一个考试零蛋被家长暴打屁股的顽童,被打得鬼哭狼嚎还嘴硬:“我出个题你会吗?你答不上就不及格!我就100分...”。
    呵呵呵... 真是没有最傻,只有更傻,FrameSniper再创犯傻新记录!我看你还能挣扎到几时!