原生 C++ 的可移植性特性
在 Visual Studio 中,有 __declspec(property)
用于创建属性与C#类似。 Borland C++ 提供了具有完全相同功能的__property
关键字。在 C++0x 中,提到了 隐式
关键字可以扩展以实现相同的功能。但它没有进入规范。
我正在寻找一种可移植且相对干净的方法来声明语法糖属性,该方法将在 Windows、OSX 和 Linux 的最新编译器中进行编译。我不关心编译器兼容性,只关心每个平台一个编译器。
我并不是在寻找需要括号来获取或设置属性的属性的替代方案,例如分隔 getter 和 setter 的重载方法。
以下是在 Visual Studio 2010 中编译的理想用法:
#define _property(_type, _name, _get, _put) __declspec(property(get=_get, put=_put)) _type _name
#define _property_readonly(_type, _name, _get) __declspec(property(get=_get)) _type _name
class Window
{
public:
_property_readonly(void*, Handle, GetHandle);
_property(bool, Visible, GetVisible, SetVisible);
void* GetHandle();
bool GetVisible();
void SetVisible(bool);
}
void main()
{
Window MainWindow;
if (!MainWindow.Visible)
MainWindow.Visible = true;
}
In Visual Studio, there is __declspec(property)
which creates properties similar to C#. Borland C++ offers the __property
keyword with the exact same functionality. In the C++0x, there is mention of a implicit
keyword that could be expanded to implement the same functionality. But it didn't make it into the spec.
I am looking for a portable and relatively clean method of declaring syntactically sugared properties that will compile in the latest compilers for Windows, OSX and Linux. I am not concerned with compiler compatibility, just one compiler per platform.
I am not looking for alternatives to properties that require parenthesis to get or set the property, such as overloaded methods separating the getters and setters.
Here is an ideal usage which compiles in Visual Studio 2010:
#define _property(_type, _name, _get, _put) __declspec(property(get=_get, put=_put)) _type _name
#define _property_readonly(_type, _name, _get) __declspec(property(get=_get)) _type _name
class Window
{
public:
_property_readonly(void*, Handle, GetHandle);
_property(bool, Visible, GetVisible, SetVisible);
void* GetHandle();
bool GetVisible();
void SetVisible(bool);
}
void main()
{
Window MainWindow;
if (!MainWindow.Visible)
MainWindow.Visible = true;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这与您所要求的类似,并且是(我希望)标准 C++...
正如您从
main
中看到的,只要您分配T 类型的值,用法就是透明的
(此处为int
)或隐式转换为T
属性,只要您在读取时将它们转换回T
值即可。但是,如果您将代替。
foo.x
传递给模板函数,行为将会有所不同,因为foo.x
的类型不是int
而是 < code>Property您也可能会遇到非模板函数的问题...调用接受
T
值的函数可以正常工作,但是T&
参数将是一个问题是因为基本上该函数要求变量直接使用地址进行访问。出于同样的原因,您当然不能将属性的地址传递给接受T*
参数的函数。This is something similar to what you are asking and is (I hope) standard C++...
As you can see from
main
the usage is transparent as long as you are assigning values of typeT
(hereint
) or implicitly convertible toT
to properties and as long you are converting them back toT
values on reading.Behavior will be different however if you for example pass
foo.x
to a template function because the type offoo.x
is notint
butProperty<Foo, int, ...>
instead.You can also have problems with non-template functions... calling a function accepting a
T
value will work fine, however aT&
parameter is for example going to be a problem because basically the function is asking a variable to access directly using the address. For the same reason you cannot pass of course the address of a property to a function accepting aT*
parameter.Clang 现在已经完全实现了 Microsoft
__declspec(property...)
并且优化得非常漂亮。 因此,您可以在所有平台上的 C++ 中使用属性,并在基于 gcc 或 c99 代码等中混合使用。我已经使用它一年多了,并等待它的到来普遍出现五年多了。
它是用于抽象结构和重构代码的最强大的 C++ 工具之一。我一直使用它来快速构建结构,然后根据性能或重组需要对其进行重构。
它是无价的,我真的不明白为什么 C++ 标准很久以前没有采用它。但话又说回来,他们使用 C++ 和模板的方式非常复杂且臃肿。
Clang 现在可以跨所有平台移植,拥有此功能真是太棒了。
使用 clang 在 Visual Studio(免费或付费版本)中进行开发几乎是无缝的,并且您可以获得令人难以置信的调试开发工具集,相比之下,这些工具集和平台上的工作只会变得痛苦。
我现在只使用
clang
进行所有 C++ 开发。另请参阅:此交叉引用帖子
Clang now has the Microsoft
__declspec(property...)
fully implemented and it optimizes beautifully. So you can use properties in your c++ across all platforms and intermix in gcc based or c99 code etc.I have been using it for over a year, and waited for this to appear universally for more than five years.
It is one of the most powerful C++ tools for abstracting structure and refactoring code. I use it all the time to allow me to quickly build a structure and then refactor it later as performance or restructuring requires it.
It is invaluable and I really don't understand why the C++ standards have not adopted it long ago. But then again, they have so much of the complex and bloated boost way of using c++ and templates.
Clang is so portable across every platform now that having this feature is fantastic.
Development within (free or paid version of) Visual Studio using clang is almost seamless and you get the incredible debugging development toolset that just makes working on other toolsets and platforms painful by comparison.
I exclusively use
clang
now for all my c++ development.See also: this cross-reference post
您正在描述“元对象”类型的功能,例如编译时或运行时定义的属性,例如那些可以通过“Java beans”或“.NET 反射”或任何多种具有高性能的方式实现的属性。 - 级脚本语言,例如 Python 和 Perl。
例如,您所描述的内容(编译时和/或运行时属性)是通过 QMetaObject 在 Qt (C++) 库中实现的。您可以直接实例化它,将其用作类中的“成员”,或者从 QObject 派生以“自动”获取元对象行为(以及其他一些东西,例如“强制转换”帮助,和信号/槽跨线程)。当然,这些都是跨平台的(例如,Win、Mac、Posix)。
我不太喜欢 __declspec() 用法,除了非常特定于平台的用法,例如通过“Microsoft Extension DLL”显式导出类型(我通常会尽量避免,如果可能的)。我认为没有任何方法可以使这种用法“跨平台”(因为该特定用法特定于 MS DLL)。
同样,编写自己的“
MyMetaObject
”类型类也不是很困难,它本质上是一个“字典”或“散列”或“关联数组”,您的对象使用它,并且它是在运行时动态填充,即使使用内部类型(例如MyColor
、MyTime
、MyFilePath
等)我已经这样做过好几次了,而且不需要做很多工作,而且可以非常优雅地工作。 (QMetaObject
通常比这些简单的方法强大得多,但它需要“moc
”编译步骤,这是生成快速查找代码的非常强大的步骤了解其属性,并启用信号/槽)。最后,您将开始稍微接触“动态 C++”领域,这意味着 C++ 语法的更轻、几乎类似脚本的用法。这里有一个提案深入探讨了这种动态用法,您可以使用这些属性编写脚本,而无需重新编译。 (这个特定的提案恰好基于
QMetaObject
类型行为,但还有其他具有类似使用思想的提案):http://www.codeproject.com/KB/cpp/dynamic_cpp.aspx
如果您搜索“Dynamic C++”或“C++ Scripting”,您可能会得到更多信息想法。其中一些东西中有一些邪恶而聪明的想法。
You're describing "meta-object" type capabilities, like compile-time or run-time defined properties, such as those that may be otherwise implemented through "Java beans" or ".NET reflection", or any number of ways with high-level scripting languages, like Python and Perl.
For example, what you're describing (compile-time and/or run-time properties) is implemented in the Qt (C++) libraries through the
QMetaObject
. You can instantiate it directly, use it as a "member" in your classes, or derive fromQObject
to "automatically" get that meta-object behavior (and some other things, like "casting" helps, and signals/slots cross-threads). Of course, these are quite cross-platform (e.g., Win, Mac, Posix).I'm not a big fan of the
__declspec()
usage, except for very platform-specific use, such as explicit exporting of types through a "Microsoft Extension DLL" (which I generally try to avoid if possible). I don't think there's any way to make such usage "cross-platform" (since that particular usage is specific to MS DLLs).Similarly, it wouldn't be very difficult to write your own "
MyMetaObject
" type class that is essentially a "dictionary" or "hash" or "associative array", which your objects use, and which is populated dynamically at runtime, even with your internal types (such asMyColor
,MyTime
,MyFilePath
, etc.) I've done that several times, and it need not be lots of work, and it can work quite elegantly. (TheQMetaObject
is typically quite a bit more powerful than these simple approaches, but it requires the "moc
" compilation step, which is a very powerful step to generate fast lookup code for its properties, and to enable signals/slots).Finally, you're starting to touch lightly into the "Dynamic C++" domain, which implies lighter, almost script-like usage of C++ syntax. Here's one proposal that goes into a bit of depth about this dynamic usage, where you script with these properties, not needing to re-compile. (This particular proposal happens to be based on the
QMetaObject
type behavior, but there are other proposals with similar usage thoughts):http://www.codeproject.com/KB/cpp/dynamic_cpp.aspx
If you google "Dynamic C++" or "C++ Scripting", you might get some more ideas. There's some wickedly clever thoughts in some of that stuff.
我喜欢 6502 的答案。它比我将介绍的解决方案使用更少的内存并且速度更快。只有我的会有一点语法糖。
我希望能够写出这样的东西(使用 PIMPL 习惯用法):
这是完整的代码(我很确定它符合标准):
以及一些实现细节:
我正在为任何想了解 UnicodeString 类的人使用 C++ Builder 。
希望它可以帮助其他人尝试符合标准的 c++ 属性。
基本机制与 6502 相同,具有相同的限制。
I like the answer of 6502. It uses both less memory and is faster than the solution i will present. Only mine will have a bit syntactic sugar.
I wanted to be able to wite something like this (with PIMPL idiom):
Here comes the completet code (I am quite sure it is standard conformant):
And some implementation details:
I am using C++ Builder for anyone who wonders about the UnicodeString class.
Hope it helps others for experimentation of Standard conforming c++ Properties.
The basic mechanism is the same as 6502, with the same limitations.