首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在ISO C++中定义或实现C#属性?

如何在ISO C++中定义或实现C#属性?
EN

Stack Overflow用户
提问于 2010-09-19 01:38:06
回答 3查看 972关注 0票数 0

如何在ISO C++中定义或实现C#属性?

假设C#代码如下:

代码语言:javascript
运行
复制
int _id;

int ID
{
    get { return _id; }
    set { _id = value; }
}

我知道C#会在编译时将get和set行转换为getXXX和setXXX方法。在C++中,程序员通常手动定义这两个函数,如下所示:

代码语言:javascript
运行
复制
int _id;

int getID() { return _id; }
void setID(int newID) { _id = newID; }

但是,我想要有C#语法或类似的东西,以便有一个简单的可用性。在C#中,我们可以使用如下属性:

代码语言:javascript
运行
复制
ID = 10;              // calling set function
int CurrentID = ID;   // calling get function

在C++中,我们可以像这样使用我们的函数:

代码语言:javascript
运行
复制
setID(10);                 // calling set function
int CurrentID = getID();   // calling get function

现在告诉我如何在ISO C++中实现C#属性。

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-19 01:56:30

正如Alexandre C.已经说过的那样,这是非常尴尬的,不值得这样做,但给出一个你可能如何做到这一点的例子。

代码语言:javascript
运行
复制
template <typename TClass, typename TProperty>
class Property
{
    private:
        void (TClass::*m_fp_set)(TProperty value);
        TProperty (TClass::*m_fp_get)();
        TClass * m_class;

        inline TProperty Get(void)
        {
            return (m_class->*m_fp_get)();
        }

        inline void Set(TProperty value)
        {
            (m_class->*m_fp_set)(value);
        }

    public:
        Property()
        {
            m_class = NULL;
            m_fp_set = NULL;
            m_fp_set = NULL;
        }

        void Init(TClass* p_class, TProperty (TClass::*p_fp_get)(void), void (TClass::*p_fp_set)(TProperty))
        {
            m_class = p_class;
            m_fp_set = p_fp_set;
            m_fp_get = p_fp_get;
        }

        inline operator TProperty(void)
        {
            return this->Get();
        }

        inline TProperty operator=(TProperty value)
        {
            this->Set(value);
        }
};

在要使用它的类中,为该属性创建一个新字段,并且必须调用Init将get/set方法传递给该属性。(在.ctor中首选)。

代码语言:javascript
运行
复制
class MyClass {
private:
    int _id;

    int getID() { return _id; }
    void setID(int newID) { _id = newID; }
public:
    Property<MyClass, int> Id;

    MyClass() {
        Id.Init(this, &MyClass::getID, &MyClass::setID);
    }
};
票数 3
EN

Stack Overflow用户

发布于 2010-09-19 01:41:08

简短的回答是:你不能。

长答案:您可以尝试通过代理类来模拟它们,但请相信我,这不值得为拥有set/get函数而带来的小麻烦。

基本上,您必须定义一个类来转发变量的所有行为。这是很难做到正确的,而且不可能被泛化。

票数 1
EN

Stack Overflow用户

发布于 2010-09-19 01:53:22

很简单。我认为,与将变量设置为公共变量相比,这甚至没有开销。但是,您不能对此进行任何进一步的修改。当然,除非您添加了另外两个模板参数,它们是获取和设置时要调用的函数的回调。

代码语言:javascript
运行
复制
template<typename TNDataType>
class CProperty
{
public:
    typedef TNDataType TDDataType;
private:
    TDDataType m_Value;
public:
    inline TDDataType& operator=(const TDDataType& Value)
    {
        m_Value = Value;
        return *this;
    }

    inline operator TDDataType&()
    {
        return m_Value;
    }
};

编辑:不要让回调函数成为模板参数,只需要在属性的构造函数中初始化常量的数据成员即可。与简单地自己编写get和set方法相比,这本身就有更大的开销,因为这样做是在get和set内部进行函数调用。回调将在运行时设置,而不是在编译时设置。

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

https://stackoverflow.com/questions/3742740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档