首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何知道哪种类型是变量?

如何知道哪种类型是变量?
EN

Stack Overflow用户
提问于 2009-02-16 10:25:12
回答 3查看 19.1K关注 0票数 11

TypeInfo( type )返回有关指定类型的信息,有任何方法知道var的类型信息吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var
  S: string;
  Instance: IObjectType;
  Obj: TDBGrid;
  Info: PTypeInfo;
begin
  Info:= TypeInfo(S);
  Info:= TypeInfo(Instance);
  Info:= TypeInfo(Obj);
end

此代码返回:

DCC错误单元1.PAS(354):E2133 TYPEINFO标准函数需要一个类型标识符

我知道非实例化的var只是一个指针地址。在编译时,编译器分析并执行类型安全检查。

在运行时,有没有办法了解更多关于var的信息,只传递它的地址?

EN

回答 3

Stack Overflow用户

发布于 2009-02-16 10:54:47

不是的。

首先,没有所谓的“非实例化变量”。您只需输入其名称并将其输入源文件即可实例化它。

第二,通过在源代码中查看变量,您已经知道了所有关于变量的知识。一旦编译程序,该变量就不再存在。在那之后,一切都只是些零碎。

指针在编译时只有一个类型。在运行时,可以对该地址执行的所有操作都已经确定。正如您已经注意到的,编译器会对此进行检查。在运行时检查变量的类型只在变量类型可能更改的语言中有用,就像在动态语言中一样。最接近德尔菲的是它的Variant类型。变量的类型总是Variant,但是可以在其中存储许多类型的值。要找出它所包含的内容,可以使用VarType函数。

当您希望使用TypeInfo获取与变量关联的类型的类型信息时,还可以直接命名您感兴趣的类型;如果变量在作用域中,则可以在调用TypeInfo时查找其声明并使用声明的类型。

如果您想将任意地址传递给一个函数,并让该函数发现其本身的类型信息,那么您就倒霉了。相反,您需要将PTypeInfo值作为附加参数传递。这就是所有内置的Delphi函数所做的。例如,当您对指针变量调用New时,编译器会插入一个额外的参数,该参数保存要分配的类型的PTypeInfo值。在动态数组上调用SetLength时,编译器将为数组类型插入一个PTypeInfo值。

The answer that you gave建议你寻找的不是你想要的东西。考虑到您的问题,我认为您正在寻找一个能够满足以下代码的假设函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var
  S: string;
  Instance: IObjectType;
  Obj: TDBGrid;
  Info: PTypeInfo;
begin
  Info:= GetVariableTypeInfo(@S);
  Assert(Info = TypeInfo(string));

  Info:= GetVariableTypeInfo(@Instance);
  Assert(Info = TypeInfo(IObjectType));

  Info:= GetVariableTypeInfo(@Obj);
  Assert(Info = TypeInfo(TDBGrid));
end;

让我们使用IsClass and IsObject functions from the JCL构建这个函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function GetVariableTypeInfo(pvar: Pointer): PTypeInfo;
begin
  if not Assigned(pvar) then
    Result := nil
  else if IsClass(PPointer(pvar)^) then
    Result := PClass(pvar).ClassInfo
  else if IsObject(PPointer(pvar)^) then
    Result := PObject(pvar).ClassInfo
  else
    raise EUnknownResult.Create;
end;

显然对上面的SInstance不起作用,但是让我们看看Obj会发生什么

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Info := GetVariableTypeInfo(@Obj);

这应该会导致访问冲突。Obj没有值,因此IsClassIsObject都将读取一个未指定的内存地址,可能不是属于您的进程的地址。您要求使用变量的地址作为输入的例程,但是仅仅使用地址是不够的。

现在,让我们更仔细地了解一下IsClassIsObject的实际行为。这些函数接受任意值,并检查该值看起来是否可能是给定类型的值,对象(实例)或类。像这样使用它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// This code will yield no assertion failures.
var
  p: Pointer;
  o: TObject;
  a: array of Integer;
begin
  p := TDBGrid;
  Assert(IsClass(p));

  p := TForm.Create(nil);
  Assert(IsObject(p));

  // So far, so good. Works just as expected.
  // Now things get interesting:

  Pointer(a) := p;
  Assert(IsObject(a));
  Pointer(a) := nil;
  // A dynamic array is an object? Hmm.

  o := nil;
  try
    IsObject(o);
    Assert(False);
  except
    on e: TObject do
      Assert(e is EAccessViolation);
  end;
  // The variable is clearly a TObject, but since it
  // doesn't hold a reference to an object, IsObject
  // can't check whether its class field looks like
  // a valid class reference.
end;

请注意,函数没有告诉您任何关于变量的信息,只告诉您它们持有的值。那么,我不会真正考虑这些函数来回答如何获取有关变量的类型信息的问题。

此外,您还说过,您所知道的有关变量的所有信息都是它的地址。您找到的函数不接受变量的地址。它们取变量的值。下面是一个演示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var
  c: TClass;
begin
  c := TDBGrid;
  Assert(IsClass(c));
  Assert(not IsClass(@c)); // Address of variable
  Assert(IsObject(@c)); // Address of variable is an object?
end;

您可能会反对我将明显是垃圾的内容传递到函数中,从而滥用这些函数。但我认为这是唯一有意义的谈论这个话题。如果您知道您永远不会有垃圾值,那么您就不需要您想要的函数了,因为您已经足够了解您的程序,可以为您的变量使用真正的类型。

总之,你问错问题了。与其询问如何确定变量的类型或内存中值的类型,还应该问自己是如何进入一个不知道变量类型和数据类型的位置的。

票数 32
EN

Stack Overflow用户

发布于 2019-02-14 21:09:35

使用泛型,现在可以获得类型信息而不指定它。某些用户表示,以下代码不会在编译过程中没有错误。从Delphi 10西雅图版23.0.20618.2753开始,它编译时没有错误,如下面的截图所示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
program TypeInfos;
{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, System.TypInfo;

type
  TTypeInfo = class
    class procedure ShowTypeInfo<T>(const X: T);
  end;

{ TTypeInfo }

class procedure TTypeInfo.ShowTypeInfo<T>(const X: T);
var
  LTypeInfo: PTypeInfo;
begin
  LTypeInfo := TypeInfo(T);
  WriteLn(LTypeInfo.Name);
end;

var
  L: Exception;
  B: Boolean;
begin
                             // Console output
  TTypeInfo.ShowTypeInfo(L); // Exception
  TTypeInfo.ShowTypeInfo(B); // Boolean
end.

票数 4
EN

Stack Overflow用户

发布于 2009-02-16 10:38:55

就我所知没有。您可以获得已发布的类属性的RTTI (运行时类型信息),但对于字符串和整数等“正常”变量则不能获得RTTI。信息根本就不在那里。

此外,在不传递类型的情况下传递var的唯一方法是使用泛型TObject参数、泛型类型(如in )或非类型化参数。我想不出另一种传递它的方法,那就是编译。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/554100

复制
相关文章
Windows下使用海康相机SDK获取图像并在Qt显示
点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,可以点个在看,让它可以帮助到更多同志
用户5908113
2020/03/11
5.2K2
Windows下使用海康相机SDK获取图像并在Qt显示
使用QT显示OpenCV读取的图片
OpenCV自带了一部分常用的GUI功能,但是更多的图像处理功能需要其他GUI框架来辅助实现,这里通过QT来显示OpenCV读取的图片。
charlee44
2020/02/25
4.2K0
使用QT显示OpenCV读取的图片
QT应用编程: 使用qcustomplot显示动态曲线、设计心电图显示页面
完整项目源码下载链接: https://download.csdn.net/download/xiaolong1126626497/18607424
DS小龙哥
2022/01/07
3.7K0
QT应用编程: 使用qcustomplot显示动态曲线、设计心电图显示页面
Qt显示Hello World
#include "widget.h" //对于 Qt 程序来说,GUI 程序是QApplication //非 GUI 程序是QCoreApplication。QApplication派生自QCoreApplication #include <QApplication> #include <QPushButton> int main(int argc, char *argv[]) { QApplication a(argc, argv); //创建一个应用程序对象,该对象有且仅有一个
zy010101
2020/04/08
5730
Qt显示Hello World
matlab使用缩放颜色显示图像-imagesc
imagesc(C) 将数组 C 中的数据显示为一个图像,该图像使用颜色图中的全部颜色。C 的每个元素指定图像的一个像素的颜色。生成的图像是一个 m×n 像素网格,其中 m 和 n 分别是 C 中的行数和列数。这些元素的行索引和列索引确定了对应像素的中心。
用户9925864
2022/12/16
2.3K0
matlab使用缩放颜色显示图像-imagesc
Qt加载XPM图像
❝XPM是一种基于ASCII编码的图像格式,一般用于创建图标。由于它是ASCII编码,很方便地在代码中使用。 ❞   Qt的QPixmap类支持XPM格式,原型如下: QPixmap::QPixmap(const char *const [] xpm)   摘取Qt源码中的"严重警告"XPM图标: static const char* const critical_xpm[]={ "32 32 4 1", ". c None", "a c #999999", "* c #ff0000", "b c #ff
Qt君
2020/05/08
1.4K0
Qt加载XPM图像
opencv显示图像
如果说我们在些项目的过程中会频繁的查看我们的图片,我们就可以直接给它封装一个方法:
淼学派对
2023/10/14
2200
opencv显示图像
Qt显示视频流——(三)
之前的两次我们已经搭建好了nginx+rtmp服务和ffmpeg推流工具,本次进行最后一步结合Qt显示视频流。
用户5908113
2019/08/23
3.2K0
Qt显示视频流——(三)
c#利用Halcon的图像显示控件显示图像
?
vv彭
2020/10/27
2.9K0
c#利用Halcon的图像显示控件显示图像
QT+QT creator+OpenCV图像灰度化
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/115569.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/10
4660
Android JetPack组件CameraX使用及修改显示图像
好久没用Kotlin写Android的代码了,刚开始写起来还有点生,不过适应了一阵也算是恢复过来了。今天这篇主要是说说Android JepPack组件中CameraX的使用,其实网上也有不少简单的例子,本篇也是参考了网的一篇文章后实现的。主要要说的还是后面,怎么在原有的图像上进行编辑显示,文末有源码的链接。
Vaccae
2020/12/17
2.6K0
Android JetPack组件CameraX使用及修改显示图像
使用opencv读入并显示一幅彩色图像,灰度化并显示,用canny算子得到图像边缘并显示
要求步骤: 1.读入彩色图像,并显示; 2.将彩色图像灰度化,并显示; 3将灰度图像,用Canny边缘算子得到图像边缘,并显示。
川川菜鸟
2021/10/18
1.2K0
图像特效显示(下)
移动是将图像看作一个整体,显示时不能像扫描那样,扫描方式有些像打开一副画,例如显示上部分的时候,下部分可以不现实,而移动则可以看成一块木板画,显示时必须按物理顺序进行,例如从上向下平移时,必须先显示下面的图像,后显示上面的图像,因此平移的算法比扫描难一些。
周旋
2022/08/07
9630
图像特效显示(下)
图像特效显示(上)
准备11月份更一个新的系列,之前看的杨淑莹老师的《数字图像处理Visual Studio C++技术实现》,里面的代码都没来得及打,而且其是基于自定义的图像类实现的,这个系列就把所有例程移植为opencv-C++实现,也就是算法逻辑用C++实现,图像对象使用opencv自带的图像类。
周旋
2022/08/07
1.1K0
图像特效显示(上)
QT应用编程: 使用QTAV得到解码视频每帧图像
参考博客: https://blog.csdn.net/xiaolong1126626497/article/details/112209279
DS小龙哥
2022/01/07
1.1K0
QT应用编程: 使用QTAV得到解码视频每帧图像
【图像篇】OpenCV图像处理(二)---图像读取与显示
在上一篇文章中,我们简要介绍了图像的基础知识,包括图像彩色通道,像素,分辨率等知识,学会这些东西,我们才能更好的理解图像处理的各种操作,今天,我们将会用上一篇文章(【图像篇】opencv图像处理(一)---图像基础知识)提到的工具--OpenCV,并用python语言调用OpenCV接口来进行实际的代码操作,一起来看看吧!
用户5410712
2022/06/01
1.1K0
【图像篇】OpenCV图像处理(二)---图像读取与显示
QT学习之如何使用Qthread(moveToThread方法)
通常在程序中需要同时做好几件事情,这时不可避免的会涉及到多线程的学习,QT学习过程中亦是如此,而QT中提供了 QThread,因为涉及到信号与槽,线程的使用也有些变化。在QThread的文档中有两种使用方法。
嵌入式小屋
2022/04/27
5K0
QT学习之如何使用Qthread(moveToThread方法)
点击加载更多

相似问题

如何使用Qt显示图像

15

使用Qt显示灰度图像

34

Qt不显示图像

23

Qt jpg图像显示

60

Qt -使用QOpenGLWidget显示图像的步骤

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文