C#-like properties in native C++?

后端 未结 11 1872
南笙
南笙 2020-11-29 04:46

In C# / .NET you can do something like this:

someThing.text = \"blah\";
String blah = someThing.text;

However, the above code does not actu

相关标签:
11条回答
  • 2020-11-29 05:12

    Yes but it's vendor specific. Microsoft has declspec(property). C++Builder's implementation is a bit more advanced (via vendor specific __property keyword) in that you could have indexed accessors (which can be of any types you wish).

    Also check this out (without relying on vendor specific keywords): http://www.codeproject.com/KB/cpp/cpp_property_indexer.aspx

    0 讨论(0)
  • 2020-11-29 05:13

    Why not to use C# language instead of C++ for native development? For that you can use IL2BC utility to generate native code from C# source and/or MSIL byte-code?

    IL2BC can be found at this site

    http://csnative.codeplex.com

    0 讨论(0)
  • 2020-11-29 05:15

    I warn you, it is not fully compatible native C++: Microsoft-specific C++ only.

    The Microsoft compiler allows you to use declspec(property), this way:

    struct S {
       int i;
       void putprop(int j) { 
          i = j;
       }
    
       int getprop() {
          return i;
       }
    
       // here you define the property and the functions to call for it
       __declspec(property(get = getprop, put = putprop)) int the_prop;
    };
    
    int main() {
       S s;
       s.the_prop = 5;    // THERE YOU GO
       return s.the_prop;
    }
    

    cf Microsoft Documentation for more details: declspec(property).

    0 讨论(0)
  • 2020-11-29 05:17

    No, there is not. You would just create getter and setter functions:

    someThing.setText("blah");
    std::string blah = someThing.getText();
    
    0 讨论(0)
  • 2020-11-29 05:18

    WARNING: This is a tongue-in-cheek response and is terrible!!!

    Yes, it's sort of possible :)

    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 ()
    };
    

    Then declare your class, declaring properties for your members:

    class Test
    {
    private:
        std::string _label;
        int         _width;
    
    public:
        Test() : Label(_label)
               , Width(_width)
        {
        };
    
        Property<std::string> Label;
        Property<int>         Width;
    };
    

    And call C# style!

    Test a;
    a.Label = "blah";
    a.Width = 5;
    
    std::string label = a.Label;
    int width = a.Width;
    
    0 讨论(0)
  • 2020-11-29 05:26

    By using std::function you can get pretty close. Featurewise everything is here.

    First create the templated Property class:

    #include <functional>
    
    template<class T>
    class Property
    {
        std::function<T (void)> _get;
        std::function<void(const T&)> _set;
    public:
        Property(
            std::function<T (void)> get,
            std::function<void(const T&)> set)
            : _get(get),
              _set(set)
        { }
    
        Property(
            std::function<T(void)> get)
            : _get(get),
              _set([](const unsigned int&){})
        { }
    
        operator T () const { return _get(); }
        void operator = (const T& t) { _set(t); }
    };
    

    Use the Property in a class by creating a get and a set method similar to what you would in do C#:

    class Test
    {
    private:
        std::string  _label;
    
    public:
        Property<std::string> Label = Property<std::string>
        (
            [this]()->std::string
            {
                return this->_label;
            },
            [this](const std::string& value)
            {
                this->_label = value;
            }
        );
        Property<unsigned int> LabelSize = Property<unsigned int>
        (
            [this]()->unsigned int
            {
                return this->_label.size();
            }
        );
    };
    

    Testing this code:

    Test test;
    test.Label = "std functional";
    
    std::cout << "label      = " << std::string(test.Label) << std::endl
              << "label size = " << int(test.LabelSize) << std::endl;
    

    will output

    label      = std functional
    label size = 14
    

    I think this is as syntactic-sugar-coated as you can get it in c++ :)

    0 讨论(0)
提交回复
热议问题