C++中的本地C++属性?

jma*_*erx 22 c++

C#/.NET中,您可以执行以下操作:

someThing.text = "blah";
String blah = someThing.text;
Run Code Online (Sandbox Code Playgroud)

但是,上面的代码实际上并没有直接与someThing的文本字符串进行交互,它使用了get和set属性.同样,可以使用只读属性.

有没有办法在本机C++中做类似的事情?(不是C++ .NET)

Moo*_*ice 45

警告:这是一个诙谐的反应,很糟糕!

是的,这有点可能:)

template<typename T>
class Property
{
private:
    T& _value;

public:
    Property(T& value) : _value(value)
    {
    }   // eo ctor

    Property<T>& operator = (const T& val)
    {
        _value = val;
        return *this;
    };  // eo operator =

    operator const T&() const
    {
        return _value;
    };  // eo operator ()
};
Run Code Online (Sandbox Code Playgroud)

然后声明您的类,为您的成员声明属性:

class Test
{
private:
    std::string _label;
    int         _width;

public:
    Test() : Label(_label)
           , Width(_width)
    {
    };

    Property<std::string> Label;
    Property<int>         Width;
};
Run Code Online (Sandbox Code Playgroud)

并调用C#风格!

Test a;
a.Label = "blah";
a.Width = 5;

std::string label = a.Label;
int width = a.Width;
Run Code Online (Sandbox Code Playgroud)

  • 我过去曾经尝试过这个,虽然我现在倾向于避免它,因为读取代码的人并没有意识到它不仅仅是一个公共领域,因为它在c ++中并不常见......但是我很惊讶地发现它通常是编译器这足以使其与直接向现场直接协调一样高效. (12认同)
  • 最后,很好地使用`T*operator&()`;) (8认同)
  • 我不知道你为什么把它作为"可怕的"序言.当然,它不像C#中的属性那么灵活,但是当涉及到语法糖果因素(实际上所有属性都是)时,我认为它很棒.丰厚而精彩的+1 (7认同)
  • @jcoder我不明白.它实质上将'm_Test`公之于众.为什么不首先公开`m_Test`并避免任何额外的编码? (4认同)
  • 感谢Moo-Juice,我能够利用这个代码通过使用断点来查找成员变量如何被设置为一个它从未被设置为的值.违规的呼叫网站有一个错误. (2认同)

Dar*_*rov 20

在.NET中,属性是真实的语法糖getset在幕后发出的函数(实际上它们不仅仅是语法糖,因为属性在生成的IL中发出并且可以与Reflection一起使用).所以在C++中你需要显式地编写那些函数,因为没有像属性这样的概念.

  • -1 正如 [Moo-Juice 的回答](http://stackoverflow.com/a/4225302/464581) 所证明的那样,“在 C++ 中,您需要明确地编写这些函数,因为没有属性这样的概念”是微不足道的,直接错误的。并且在 C++ 中还有其他方法来处理属性,包括源代码预处理。然而,C++ 中可移植属性的技术可能性并不意味着这样做是个好主意...... :-) (2认同)

Ste*_*and 16

我警告你:它不是本机C++; 它只是微软特有的.但你可以使用declspec(property):

struct S {
   int i;
   void putprop(int j) { 
      i = j;
   }

   int getprop() {
      return i;
   }

   __declspec(property(get = getprop, put = putprop)) int the_prop;
};

int main() {
   S s;
   s.the_prop = 5;    // THERE YOU GO
   return s.the_prop;
}
Run Code Online (Sandbox Code Playgroud)

cf MSDN,declspec(property).


Adr*_*n W 8

Moo-Juice的答案看起来很酷,但有一个缺点:你不能像TC#那样使用像普通表达式这样的属性.

例如,

  • a.text.c_str()不会编译(‘class Property<std::basic_string<char> >’ has no member named ‘c_str’)
  • std::cout << a.text不会编译(template argument deduction/substitution failed)

我建议以下增强功能template<typename T> class Property:

T& operator() ()
{
    return _value;
}
T const& operator() () const
{
    return _value;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问该属性的成员(),例如:

 char const *p = a.text().c_str();
Run Code Online (Sandbox Code Playgroud)

并且您可以在必须推导出类型的表达式中使用该属性:

std::cout << a.text();
Run Code Online (Sandbox Code Playgroud)