Thread: implementing property in c++ just like c#?

  1. #1
    بابلی ریکا Masterx's Avatar
    Join Date
    Nov 2007
    Location
    Somewhere nearby,Who Cares?
    Posts
    497

    implementing property in c++ just like c#?

    hello all .
    i was recently coding a test application in Visual C++.net and i faced sth that , to me was strange .
    we all know that in c# we can access properties very easily sth like :
    Code:
    btn.Text = "Setting the text ";
    string variable = btn.Text;
    but in c++ we have sth like these:
    Code:
    btn->SetText("sth");
    string var = btn->GetText();
    there is always a Set() function to set the values, and Get() function to retrive the values.!
    having all said , i saw the c# conventional use of property in c++, i mean i could write !:
    Code:
    btn->Text = "sth goes here!";
    string variable = btn->Text;
    !and i wondered if it is really possible to have sth like this in c++ .
    thats all , so is it all MS VC++.net specific ? or no this can be achieved in general c++ too ?
    i will be very thankful if anyone gives me an answer
    and isn't there anyway to implement such thing in c++? ( i mean writing properties just like what we have in c# ?)
    Thank you in advance
    Highlight Your Codes
    The Boost C++ Libraries (online Reference)

    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.."
    Bill Bryson


  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Code:
    btn->Text = "sth goes here!";
    string variable = btn->Text;
    Yeah, if btn::Text is of type string as well as a public member that syntax will work as is.

    But part of the Object-Oriented mantra of C++ is that you hide the innards (read: data members) of your class, so btn::Text is probably a private member, and that's why you have the get and set functions.
    Consider this post signed

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Properties don't mean that the members are public.

    It is also possible to overload the accessor, so they have the same name.

    Code:
    btn->Text("sth");
    string var = btn->Text();
    Similarly, it is possible to use types that overload operator= and conversion for the value type.

    For example:
    Code:
    namespace properties
    {
        enum {
            no_restrictions = 0,
            no_setter = 1,
            no_mutable_getter = 2,
            no_getter = 4,
            immutable = no_setter | no_mutable_getter
        };
    
    namespace detail
    {
        template <class Derived, class ValueType, bool HasSetter>
        struct Setter
        {
            Derived& operator= (const ValueType& value)
            {
                static_cast<Derived&>(*this).value = value;
                return static_cast<Derived&>(*this);
            }
        };
        template <class Derived, class ValueType>
        struct Setter<Derived, ValueType, false> {};
    
        template <class Derived, class ValueType, bool HasGetter, bool HasMutableGetter>
        struct Getter
        {
            operator ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType>
        struct Getter<Derived, ValueType, true, false>
        {
            operator const ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType, bool Ignored>
        struct Getter<Derived, ValueType, false, Ignored>{};
    } //detail
        template <class ValueType, unsigned DisabledFlag = properties::no_restrictions>
        class DefaultProperty:
            public detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >,
            public detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >
        {
            ValueType value;
        public:
            explicit DefaultProperty(const ValueType& value = ValueType()): value(value) {}
            using detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >::operator=;
        private:
            friend class detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >;
            friend class detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >;
        };
    }
    
    struct X
    {
        properties::DefaultProperty<int> a;
        properties::DefaultProperty<int, properties::no_setter> b;
        properties::DefaultProperty<int, properties::immutable> c;
    };
    
    #include <iostream>
    int main()
    {
        X x, y;
        y.a = x.a = 100;
        std::cout << x.a << ' ' << y.a << '\n';
        //x.b = 50;
        std::cout << x.b << '\n';
        //x.c = 75;
        int c = x.c;
        //int& d = x.c;
        std::cout << c << '\n';
    }
    This example allows some customizability as to whether the default implementations of getters and setters are available or not (commented-out lines cause errors).

    Other property types might be added that allow calling a method of the parent class.
    Last edited by anon; 11-21-2010 at 07:55 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Why would you want this in C++? C++ has multiple ways to do this but properties are not part of the language and really all they do is encapsulate getters/setters which C++ has been doing for many many years.

  5. #5
    The Autodidact Dante Wingates's Avatar
    Join Date
    Apr 2010
    Location
    Valhalla
    Posts
    56

    Cout is printing numbers from right to left

    Damn I can't believe I did that!

    Sorry, I was going to start a new thread, and then posted here.
    2B OR !2B? That is the question!

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by anon View Post
    Properties don't mean that the members are public.

    It is also possible to overload the accessor, so they have the same name.

    Code:
    btn->Text("sth");
    string var = btn->Text();
    Similarly, it is possible to use types that overload operator= and conversion for the value type.

    For example:
    Code:
    namespace properties
    {
        enum {
            no_restrictions = 0,
            no_setter = 1,
            no_mutable_getter = 2,
            no_getter = 4,
            immutable = no_setter | no_mutable_getter
        };
    
    namespace detail
    {
        template <class Derived, class ValueType, bool HasSetter>
        struct Setter
        {
            Derived& operator= (const ValueType& value)
            {
                static_cast<Derived&>(*this).value = value;
                return static_cast<Derived&>(*this);
            }
        };
        template <class Derived, class ValueType>
        struct Setter<Derived, ValueType, false> {};
    
        template <class Derived, class ValueType, bool HasGetter, bool HasMutableGetter>
        struct Getter
        {
            operator ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType>
        struct Getter<Derived, ValueType, true, false>
        {
            operator const ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType, bool Ignored>
        struct Getter<Derived, ValueType, false, Ignored>{};
    } //detail
        template <class ValueType, unsigned DisabledFlag = properties::no_restrictions>
        class DefaultProperty:
            public detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >,
            public detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >
        {
            ValueType value;
        public:
            explicit DefaultProperty(const ValueType& value = ValueType()): value(value) {}
            using detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >::operator=;
        private:
            friend class detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >;
            friend class detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >;
        };
    }
    
    struct X
    {
        properties::DefaultProperty<int> a;
        properties::DefaultProperty<int, properties::no_setter> b;
        properties::DefaultProperty<int, properties::immutable> c;
    };
    
    #include <iostream>
    int main()
    {
        X x, y;
        y.a = x.a = 100;
        std::cout << x.a << ' ' << y.a << '\n';
        //x.b = 50;
        std::cout << x.b << '\n';
        //x.c = 75;
        int c = x.c;
        //int& d = x.c;
        std::cout << c << '\n';
    }
    This example allows some customizability as to whether the default implementations of getters and setters are available or not (commented-out lines cause errors).

    Other property types might be added that allow calling a method of the parent class.
    Nice approach!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    I had been thinking about implementing properties too until I realized that they destroy encapsulation. I'd minimize using getters/setters.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Properties do not destroy encapsulation. They are a different form of get/set syntax. That's all.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Elysia is correct. There isn't anything magical about properties in C#. They are a welcome addition to any language b/c I know personally I get tired of writing getters and setters in C++ but alas C++ does not yet have them so I have to. Perhaps one day C++ will have them and perhaps not. The point is that C++ does not 'need' them but they would be 'nice to have.'

  10. #10
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    C# doesn't *need* them either, but they make a lot of things easier, especially in GUI programming.

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by Bubba View Post
    Elysia is correct. There isn't anything magical about properties in C#. They are a welcome addition to any language b/c I know personally I get tired of writing getters and setters in C++ but alas C++ does not yet have them so I have to. Perhaps one day C++ will have them and perhaps not. The point is that C++ does not 'need' them but they would be 'nice to have.'
    So why not make them yourself? It's very well possible (as anon showed and as you undoubtedly knew), and he's only showing a very basic form. You could add a lot of functionality such setting functions to validate the set value, and templates where for instance you can specify allowed ranges.
    When designed properly, it would be fairly easy to use, probably as easy as in C#.

  12. #12
    بابلی ریکا Masterx's Avatar
    Join Date
    Nov 2007
    Location
    Somewhere nearby,Who Cares?
    Posts
    497
    Quote Originally Posted by anon View Post
    Properties don't mean that the members are public.

    It is also possible to overload the accessor, so they have the same name.

    Code:
    btn->Text("sth");
    string var = btn->Text();
    Similarly, it is possible to use types that overload operator= and conversion for the value type.

    For example:
    Code:
    namespace properties
    {
        enum {
            no_restrictions = 0,
            no_setter = 1,
            no_mutable_getter = 2,
            no_getter = 4,
            immutable = no_setter | no_mutable_getter
        };
    
    namespace detail
    {
        template <class Derived, class ValueType, bool HasSetter>
        struct Setter
        {
            Derived& operator= (const ValueType& value)
            {
                static_cast<Derived&>(*this).value = value;
                return static_cast<Derived&>(*this);
            }
        };
        template <class Derived, class ValueType>
        struct Setter<Derived, ValueType, false> {};
    
        template <class Derived, class ValueType, bool HasGetter, bool HasMutableGetter>
        struct Getter
        {
            operator ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType>
        struct Getter<Derived, ValueType, true, false>
        {
            operator const ValueType& ()
            {
                return static_cast<Derived&>(*this).value;
            }
            operator const ValueType& () const
            {
                return static_cast<const Derived&>(*this).value;
            }
        };
    
        template <class Derived, class ValueType, bool Ignored>
        struct Getter<Derived, ValueType, false, Ignored>{};
    } //detail
        template <class ValueType, unsigned DisabledFlag = properties::no_restrictions>
        class DefaultProperty:
            public detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >,
            public detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >
        {
            ValueType value;
        public:
            explicit DefaultProperty(const ValueType& value = ValueType()): value(value) {}
            using detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >::operator=;
        private:
            friend class detail::Setter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_setter) == 0
            >;
            friend class detail::Getter<
                DefaultProperty<ValueType, DisabledFlag>,
                ValueType,
                (DisabledFlag & properties::no_getter) == 0,
                (DisabledFlag & properties::no_mutable_getter) == 0
            >;
        };
    }
    
    struct X
    {
        properties::DefaultProperty<int> a;
        properties::DefaultProperty<int, properties::no_setter> b;
        properties::DefaultProperty<int, properties::immutable> c;
    };
    
    #include <iostream>
    int main()
    {
        X x, y;
        y.a = x.a = 100;
        std::cout << x.a << ' ' << y.a << '\n';
        //x.b = 50;
        std::cout << x.b << '\n';
        //x.c = 75;
        int c = x.c;
        //int& d = x.c;
        std::cout << c << '\n';
    }
    This example allows some customizability as to whether the default implementations of getters and setters are available or not (commented-out lines cause errors).

    Other property types might be added that allow calling a method of the parent class.
    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.

    Thank you Dear anon , i really appreciate the time and effort you spent to clarify this for me and the others . big thanks .



    but how is it possible to extend the functionality of this package ? i mean using this package we can only have simple assignment setters and getters avoided, and for any new setters/getters we need to recode some parts again alot !
    any idea on this ?
    i'm more specifically into knowing if making sth such as this in c++ is possible:
    and if it is , it would be a nice idea to try and add it to the boost library maybe, before the standard committee does so ? ( in case they care to do such a thing at all! ?)

    whats your idea?
    Last edited by Masterx; 11-22-2010 at 09:11 AM.
    Highlight Your Codes
    The Boost C++ Libraries (online Reference)

    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.."
    Bill Bryson


  13. #13
    بابلی ریکا Masterx's Avatar
    Join Date
    Nov 2007
    Location
    Somewhere nearby,Who Cares?
    Posts
    497
    Quote Originally Posted by Bubba View Post
    Why would you want this in C++? C++ has multiple ways to do this but properties are not part of the language and really all they do is encapsulate getters/setters which C++ has been doing for many many years.
    i know there are ways, but this elegant way , is really making stuff easier .
    Quote Originally Posted by Elysia View Post
    Properties do not destroy encapsulation. They are a different form of get/set syntax. That's all.
    yes indeed .
    Quote Originally Posted by Bubba View Post
    Elysia is correct. There isn't anything magical about properties in C#. They are a welcome addition to any language b/c I know personally I get tired of writing getters and setters in C++ but alas C++ does not yet have them so I have to. Perhaps one day C++ will have them and perhaps not. The point is that C++ does not 'need' them but they would be 'nice to have.'
    *
    Quote Originally Posted by Elkvis View Post
    C# doesn't *need* them either, but they make a lot of things easier, especially in GUI programming.
    *
    if im not mistaken , i've seen that c# itself is doing it in traditional c++ way ( using setters and getters ) at backstage, so that the redundancy is avoided , and the code is clearer and just more elegant .
    all in all , Bubba's idea on the subject is greatly desired .
    Quote Originally Posted by EVOEx View Post
    So why not make them yourself? It's very well possible (as anon showed and as you undoubtedly knew), and he's only showing a very basic form. You could add a lot of functionality such setting functions to validate the set value, and templates where for instance you can specify allowed ranges.
    When designed properly, it would be fairly easy to use, probably as easy as in C#.
    really if sth can be done on this subject and get submitted to the c++ committee or boost libraries , that would be awesome !
    Highlight Your Codes
    The Boost C++ Libraries (online Reference)

    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.."
    Bill Bryson


  14. #14
    The larch
    Join Date
    May 2006
    Posts
    3,573
    There would seem to be great problems implementing more advanced properties.

    For example, check out this.

    1) Overhead for the property.
    2) Limited signature for the getter and setter methods.
    3) Need to give the pointer to parent to each property in the constructor.
    4) Need to code a copy constructor to do the same.

    It just doesn't seem to be worth it.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    There is a problem with getters with the current C++ standard due to implicit conversion operators. They cause unwanted side effects.
    This should be fixed in C++0x, though, when we can make them explicit.

    Microsoft also have their own non-standard properties extension for C++, for those interested in such things.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. static property
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 06-12-2008, 01:03 AM
  2. C++/CLI Property
    By psychopath in forum Windows Programming
    Replies: 5
    Last Post: 07-11-2006, 09:45 PM
  3. Problem with a file parser.
    By Hulag in forum C++ Programming
    Replies: 7
    Last Post: 03-17-2005, 09:54 AM
  4. Dialog Box & Property Sheet :: MFC
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 08-01-2002, 01:33 PM
  5. Property Sheets :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 05-09-2002, 03:04 PM