我在一个窗体中调用一个自定义类中的方法,要传递一个AdoQuery变量过去。如:
  类.creat(aq1);
类中的一些定义如下(只是思路,不是原程序):
  Paq=^TAdoQuery;//private
    
  procedure creat(_aq:tadoquery);
  begin
    Paq:=@aq;
    ExecOpen(Paq^);
  end;
  procedure ExecOpen(_aq:tadoquery);
  begin
    _aq.open;
  end;
如果按以上方法调用则会出现错误。所以我在类中声明一个私有的变量PPaq:tadoquery;在creat过程中用PPaq:=_aq;在ExecOpen过程中调用此私有变量,执行成功。
但回头我想类中声明的PPaq变量和传递过来的参数不是同一个对象,但执行后,前一个窗体的DBgrid显示也随着变化。
请教:
  delphi中的TAdoQuery对象本身是不是就是指针?这样的对象都有哪些是?
  如果不是,上面的程序我如果想用指针来操作应该怎样用,声明一个tadoquery的变量倒是可以解决问题,但我想这会不会占用内存从而影响速度?
  
  谢谢!!!

解决方案 »

  1.   

    是引用类型,和指针差不多。。
    类的实例都是引用。string 也是。
      

  2.   

    传过一个数据集,在clon出一个来,对clon出来数据进行操作,就不会有行后,前一个窗体的DBgrid显示也随着变化的现象了
      

  3.   

    To:herofy(雄鸡破晓)
    事实确是如此,我是这样做的
      procedure creat(_aq:tadoquery);
      begin
        PPaq:=tadoquery.creat(nil);//PPaq为私有变量
        PPaq:=_aq;
      end;
      procedure ExecOpen();
      begin
        PPaq.open;
      end;      
    如此运行后,调用此过程的窗体,也就是前一个窗体的DBgrid确实随着变化了。
    所以我才想问tadoquery类型的变量是不是就是一种指针类型?
      

  4.   

    我们知道指针可以是空,但是引用不能是空。我们可以这样定义指针:
    int *p=0; //空指针
    int *q; //未初始化指针,修改*p将非常危险
    但是不能这样定义引用:
    int &h; //错误
    int y;
    int &u=y; //OK
    也就是引用不可能为空,还有要注意的就是引用定义后不能再指定为其他的变量了,而指针却能。好比说,指针是变量,引用是常量。因此下面的代码要特别小心:
    char* p=0; //p为空指针
    char& i=*p;
    i='p'; //错误
    还有一点就是operator[],假设我们有类sevecol,重载了operator[],如果operator[]返回指针,那么:
    *sevecol[10]=.....
    这样给人的感觉不是很自然,最好是operator[]返回引用,那么:
    sevecol[10]= .....就OK。
    可以看出在这儿引用和指针是本质上不同的两个东东,对C++程序员来说弄清这一点是很必要的。
    而我们在JAVA中,一般是这样定义一个类对象的引用的。
    class A 
    {
    ……
    //类定义语句
    }
    A refA = new A(); //A()是类的构造函数,和类名相同
    用new A()定义一个对象,占据一定的内存,现在的问题是 refA到底是什么?说它是指向对象的指针有道理,虽然JAVA不支持指针;说它是对象的引用也极有道理的。一般认为,这个引用的本质就是一个指向对象的指针,这似乎把指针和引用等同起来了。正如前面所说的C++中引用和指针是有本质区别的。就这个例子来说,引用就可看作是对象本身,是对象的一个别名而已,而指针我们就不能这么理解了。怎么样,是不是有点自相矛盾呢。如果纯粹用C++的规则来看这个问题,可能永远也不能把问题说清楚,只能是越说越糊涂。
    这就是JAVA和C++的一点区别吧,所以为了方便理解,总结出以下几点:
    1.JAVA不支持指针。
    2.指针和引用其实在内部表示是一样的,编译时也一样编译。
    3.JAVA禁止访问内存,使对象封装的更好,可以有效避免重写内存。
    4.对象是内存中的一段代码,指向它的指针保存于对象引用变量中。
    5.当你定义一个对象变量时,事实上只是定义了一个地址,用以保存对象的内存位置。
    6.引用变量用以保存对象的引用或指针,但这里的指针不象C++所用的指针,只是指向内存中的对象的概念,这些对象可以是类实例、实现接口或数组的类实例。
    也许是思维的惯性问题,老是用C++的规则来考虑JAVA的问题。换换思维方式应该是很不错的选择。相似的问题在DELPHI中也是一样,如:Form1:TForm1,可以说Form1是一个引用,也可以说Form1是一个指针,要说明的是在 DELPHI和JAVA中的这种引用和在C++中的引用是完全不同的,说到底就是指针。你似乎可以用一个整形变量来保存Form1,并用来传递:
    Var
    I:integer;
    Form2:TForm;
    begin
    I:=integer(Form1); //保存Form1的地址值,它指的就是对象
    Form2:=TForm(I);
    ShowMessage(Form2.caption);
    end;
    人们现在把这种对象变量的类型统一叫做reference。这样,当要传递对象的参数时就只需传递该对象的引用(只是四个字节的地址)来实现按地址传递,而非按值传递了,这就避免了数据的大量移动。Macro Canto曾这样描述这种对象引用模型:“它的基本思想是,一个类的每个变量,并不保存对象的值,而是保存一个引用,或一个指针,以来说明对象存储的内存位置,使用这种方法的唯一问题是,当声明一个变量时,我们不能在内存中建立一个对象,只是保存对象引用的内存地址-----一种指针。”这是一段很精辟的概括,令人回味无穷,对我在这个问题的理解上起了很大的引导作用。
    对于这个问题就谈这么多了,我想问题从混沌到稍微明白是要有个过程的,其中关键还是看自己怎么去认识了。以上是自己在学习过程中遇到的一些小问题,自己按照经验就做了不知对错与否的结论,虽然某些问题还是有必要再讨论的。希望能得到大家的指正,不胜感激!
      

  5.   

    指针不能为空 ??
    var btn:TButton;
    begin
      btn:=nil;//这里可以吧。
    end;
    请指教。
      

  6.   

    // 是这样吧:
    // 传一个TADOQuery过去,把它打开,如果成功打开返回True,否则返回False;
    function OpenDataSet(const adoq: TADOQuery): Boolean;
    begin
      Result := False;
      try
        adoq.Open;
        Result := True;
      except
        Exit;
      end;
    end;