BCB 是否支持静态属性?

勉励前行 2011-05-16 09:11:19
delphi是支持静态属性的,但我在BCB中找不出对应的写法.

class A
{
static String fv ;
static String GetValue() {return fv ; }
static void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue }; //这样写会发生内部的编译错误..
static __property String Value = { read = GetValue , write = SetValue }; //这样写也不行
//不知道怎样写了
};


delphi代码:
A = class
private
class procedure SetValue(const Value: string);
class function GetValue: string;
...//省略
published
property Value: string read GetValue write SetValue;
end;

//想知道 是否BCB 不支持静态的属性这个概念,还是编译器错误.
[BCC32 Error] Unit5.cpp(23): F1004 Internal compiler error at 0x5b5d3d7 with base 0x5b20000
BCB2007给出这样的编译信息,看不出什么问题.
...全文
231 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
啊,原来__classmethod在C++Builder 2009中就有了,我居然一直不知道。:)
勉励前行 2011-05-17
  • 打赏
  • 举报
回复
总結一下:
// 方式1: 正常方式, 調用時參數含實例指針, 不能脫離實例使用 A::Value
class A
{
static String fv ;
String GetValue() {return fv ; }
void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
};
// 方式2: static 靜態方法 調用時不帶其他參數 無須實例,可以使用 A::Value
class A
{
static String fv ;
static String GetValue() {return fv ; }
static void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
};
// 方式3: __classmethod 類方法,調用時參數含TMetaClass * ,無須實例,可以使用 A::Value
class A : public TObject
{
static String fv ;
__classmethod String GetValue() {return fv ; }
__classmethod void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
};

方式3,__classmethod 方法,一定要從 TObject 繼承,其他兩種無須繼承於 TObject .

有了這3種方式,就能夠完整對應delphi中的各種方法及屬性,翻譯delphi代碼就輕松了。

上面三種方式,在 BCBXE中 調試通過,正常使用。在 B2007中方法2,3是不行的。想要好用,就更新版本吧.
Jim@luckeeinc.com 2011-05-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 ppower 的回复:]
看來是误会了, 术语不明确引起误会.

我指的是 静态的 property , 不是静态变量. 因为静态变量有时也说成是静态属性的,我们误会了.是我的用语不够谨慎引起的,应该说 静态 property , 而不要使用容易误解的 "静态属性"

对应上面的例子, 也就是 A::Value
[/Quote]

理解你的意思了
class A
{
static String fv;
protected:
String GetValue() {return fv; }
void SetValue(String v) {fv = v ;}
public :
__property AnsiString MyValue = { read = GetValue, write = SetValue };
};
这样写在bcb 6.0下编译没问题
但是如果写成static String GetValue() 编译就出错了 刚刚查了一下JSP季老大以前的回复 他是说"read=以及write=后面的,可以是class内部的成员变量,也可以是class的成员函数" 但是不知道为什么用静态成员函数就不行 没那么深入学习 借PPower宝地同问
  • 打赏
  • 举报
回复
应该是BUG,“Internal compiler error”这不是语法不支持导致的,而是编译过程中莫名其妙的神秘原因导致的。

我也碰到过,比如在XE中用ASM代码调用printf,如果“#include <iostream>”则没问题,如果“#include <stdio.h>”则编译出现“Internal compiler error”,但是用VC编译同样的代码则没有问题。
My_Love 2011-05-16
  • 打赏
  • 举报
回复
曾经BCB6用得一个hpp文件出这个错。(控件是Delphi的)
勉励前行 2011-05-16
  • 打赏
  • 举报
回复
看來是误会了, 术语不明确引起误会.

我指的是 静态的 property , 不是静态变量. 因为静态变量有时也说成是静态属性的,我们误会了.是我的用语不够谨慎引起的,应该说 静态 property , 而不要使用容易误解的 "静态属性"

对应上面的例子, 也就是 A::Value
Jim@luckeeinc.com 2011-05-16
  • 打赏
  • 举报
回复
static String fv; 这个叫静态属性
get 和 set如果用static修饰的话应该是叫静态方法
勉励前行 2011-05-16
  • 打赏
  • 举报
回复
TO Ring_Pt : get和set不要static修饰 , 就不叫静态属性了,和正常属性没有差别了.

按 fxworld 所说,应该是 B2007 未支持或者说BUG , 到 B2010 就正常了.

不知道是否 B2010 支持这样的静态属性用法: A::Value = "Test..." ;

我可是要装个 B2010 或XE 才能测试到. 以前装的都给 uninstall 了

fxworld 2011-05-16
  • 打赏
  • 举报
回复
//在2010下编译通过
class A
{
static String fv ;
static String GetValue() {return fv ; }
static void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
};
Jim@luckeeinc.com 2011-05-16
  • 打赏
  • 举报
回复
bcb支持静态属性的
fv定义成static后好像就可以了吧get和set都不要再去用static修饰了
class A
{
static String fv;
protected:
String GetValue() {return fv; }
void SetValue(String v) {fv = v ;}
public :
__property AnsiString MyValue = { read = GetValue, write = SetValue };
};

AnsiString A::fv = "";
void __fastcall TForm1::btn1Click(TObject *Sender)
{
A *a;
a->MyValue = "test1";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btn2Click(TObject *Sender)
{
A *a;
ShowMessage(a->MyValue);
}
//---------------------------------------------------------------------------
先点button1 再点button2 showmessage出来的就是test1
没有用static去修饰过get和set
勉励前行 2011-05-16
  • 打赏
  • 举报
回复
class A
{
static String fv ;
String GetValue(int a,int b, int c) {return fv ; }
void SetValue(String v,int xxx,String ccc) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
};
//再测试原来在XE中,虽然支持 static 的方法,但根本不检查 read write 函数的原型, 无论原型如何写,均通过编译,但是通过编译的类却无法使用该属性,因为调用时不能给出对应的参数列表, 所以函数原型不对时,在使用到该属性时出错.
//而在B2007中,严格检查函数原型是否匹配,但是不支持 static 的方法.

知道是BUG,修正了,但修正得也太马虎了吧.

勉励前行 2011-05-16
  • 打赏
  • 举报
回复
仔细对比了一下几种方式:
procedure xxx; //正常 类方法 调用时含 实例指针 self
class procedure xxx; //类方法 调用时含 类类型指针 TMetaClass *
class procedure xxx; static; // 兼容 C++ static方法, 调用时不含任何额外指针
翻译成BCB为:
void xxx(void);
static void xxx(TMetaClass *);
static void xxx(void);

以前是没注意这几种方式, 谢谢DelphiGuy
  • 打赏
  • 举报
回复
class procedure xxx; static;这就是为了完全兼容C++的static方法搞出来的。:)
勉励前行 2011-05-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 delphiguy 的回复:]
C++的static方法和Delphi的class方法并不完全等价,而和static class方法等价(class procedure xxx; static;),区别在于前者调用时隐含传入一个类类型指针或者类实例指针,后者没有。
所以Delphi可以有class property而CB不能支持,原因10楼已经说了。
[/Quote]

不清楚delphi中,类方法定义:
A = class
private
procedure xxx;
class procedure xxx;
class procedure xxx; static;
end;
这几种xxx方法的具体区别. delphiguy 可以说说不

我原认为只有两种,可现在跑出来三种,原来我是不知道有第三种方式.
勉励前行 2011-05-16
  • 打赏
  • 举报
回复
刚装了个 XE 来测试;
class A
{
static String fv ;
static String GetValue() {return fv ; }
static void SetValue(String v) {fv = v ;}
public :
__property String Value = { read = GetValue , write = SetValue };
// static __property String Value = { read = GetValue , write = SetValue };
// static __property 不支持这样的写法.
};
String A::fv ;

String Test()
{
A::Value = "TEST";
return A::Value ;
}

如果GetValue 或 SetValue 有一个不是静态方法,则该属性也不是静态的,也就不能使用 A::Value , 编译器能够正确识别出这一点....属性否是静态的,取决于其读写方法是否静态的.


应该是B2007及之前的版本不行,在B2010后可以了.
__property 是BCB独有的东西,本来就是为了兼容delphi,使用VCL而引入的关键字, 编译器爱如何解释就如何解释,只是它应该能完成 delphi中的property 同样的功能. 否则不能全面兼容VCL. 所以我认为的 B2007及之前的版本中,是个BUG.

另外, BCB选择的语法方式是依据读写方法是否静态的来识别属性是否静态的,而不是直接声明某个属性是静态的.也就是 static __property 是不支持的. 虽然我倾向于直接声明该属性是静态的.否则不是静态的,好象更符合 C++中 static 关键字的做法. 不过 BCB作出了这种语法选择,应该是认为这样更符合delphi的习惯,我们只有顺从.

  • 打赏
  • 举报
回复
前面忘记写了,static __property String Value = { read = GetValue , write = SetValue }; 这样写的编译错误信息:
[BCC32 Error] Unit3.cpp(19): E2092 Storage class 'property' is not allowed here
  • 打赏
  • 举报
回复
经过实际测试:
__property String Value = { read = GetValue , write = SetValue }; //这样写XE可以编译通过
static __property String Value = { read = GetValue , write = SetValue }; //这样写不行
  • 打赏
  • 举报
回复
C++的static方法和Delphi的class方法并不完全等价,而和static class方法等价(class procedure xxx; static;),区别在于前者调用时隐含传入一个类类型指针或者类实例指针,后者没有。
所以Delphi可以有class property而CB不能支持,原因10楼已经说了。
hemiya 2011-05-16
  • 打赏
  • 举报
回复
至于为什么说bcb的属性的读写函数有隐含地this指针,这个有个间接证明。
以前我写过的一个软件中使用过属性的读写函数为虚函数,属性的读写函数声明为纯虚函数也是可以的。
hemiya 2011-05-16
  • 打赏
  • 举报
回复
__property只是bcb语法层次的东西,实际上编译后根本就没有这个东西。
至于为什么不允许用static和使用static的函数,
以下个人理解(不一定正确):
应该和__property语法经过bcb编译后有关。
经过bcb编译后的属性的读写函数,需要隐含地this指针,例如:

class a
{
public:
__property int w = { read=getW, write=setW };

private:
int getW(){ return _w; }
void setW(int v){ _w=v; }
int _w;
};

当我们写
w = 123;
的时候最后经编译后会变成
this->setW(123);
当setW为静态的时候,因为setW没有隐含的this指针,但是bcb的编译器需要这个隐含地this指针两个冲突了,所以bcb不支持属性的静态读写函数。
加载更多回复(1)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧