CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    about properties

    i have found these nice code for build properties and works fine with int type, but not with string(i don't have tested the others types):

    Code:
    #include <iostream>#include <string>
    #include <assert.h>
    
    
    //property class
    #define READ_ONLY 1
    #define WRITE_ONLY 2
    #define READ_WRITE 3
    
    
    template <typename Container, typename ValueType, int nPropType>
    class property
    {
    public:
    property()
    {
      m_cObject = NULL;
      Set = NULL;
      Get = NULL;
    }
    //-- This to set a pointer to the class that contain the
    //   property --
    void setContainer(Container* cObject)
    {
      m_cObject = cObject;
    }
    //-- Set the set member function that will change the value --
    void setter(void (Container::*pSet)(ValueType value))
    {
      if((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
        Set = pSet;
      else
        Set = NULL;
    }
    //-- Set the get member function that will retrieve the value --
    void getter(ValueType (Container::*pGet)())
    {
      if((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
        Get = pGet;
      else
        Get = NULL;
    }
    //-- Overload the '=' sign to set the value using the set
    //   member --
    ValueType operator =(const ValueType& value)
    {
      assert(m_cObject != NULL);
      assert(Set != NULL);
      (m_cObject->*Set)(value);
      return value;
    }
    //-- To make possible to cast the property class to the
    //   internal type --
    operator ValueType()
    {
      assert(m_cObject != NULL);
      assert(Get != NULL);
      return (m_cObject->*Get)();
    }
    private:
      Container* m_cObject;  //-- Pointer to the module that
                             //   contains the property --
      void (Container::*Set)(ValueType value);
                             //-- Pointer to set member function --
      ValueType (Container::*Get)();
                             //-- Pointer to get member function --
    };
    
    
    //testing the property class
    class PropTest
    {
    public:
      PropTest()
      {
        Count.setContainer(this);
        Count.setter(&PropTest::setCount);
        Count.getter(&PropTest::getCount);
        Name.setContainer(this);
        Name.setter(&PropTest::setName);
        Name.getter(&PropTest::getName);
      }
      int getCount()
      {
        return m_nCount;
      }
      void setCount(int nCount)
      {
        m_nCount = nCount;
      }
      property<PropTest,int,READ_WRITE> Count;
    
    
    
    
      char * getName()
      {
        return m_Name;
      }
      void setName(char  *nCount)
      {
        m_Name = nCount;
      }
      property<PropTest,char *,READ_WRITE> Name;
    
    
    
    
    private:
      int m_nCount;
      char *m_Name;
    };
    
    
    using namespace std;
    int main()
    {
        PropTest a;
        a.Count=100;
        cin >> a.Name[0];
        cout << a.Name;
        cout << a.Count << endl;
        return 0;
    }
    even with char* the windows give me an error and close the program.
    if i use string, i get istream errors. so what is the problem?
    (yes now i can use C++11 code)

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: about properties

    Quote Originally Posted by Cambalinho View Post
    i have found these nice code for build properties and works fine with int type, but not with string(i don't have tested the others types):
    What is this?
    Code:
    #include <iostream>#include <string>
    You should fix the above so that you have one #include per line.
    even with char* the windows give me an error and close the program.
    You declared a pointer, and it points to junk. You cannot use it until you point that pointer somewhere valid. Where do you take that char* and point it to a valid character?
    Code:
      cin >> a.Name[0];
    What is that line above supposed to do? What is Name[0]? Is it that char* I mentioned? If so, again, where do you initially point that pointer to a valid memory address?

    To be more blunt, you using char* is no different than if you used an int*, double*, float*, etc. A char* is not a string -- it is a pointer, no different than any other pointer. If you are using pointers, that pointer must point to a valid memory location before you read or write to it. This is fundamental C++ knowledge, and by jumping into templates without knowing the fundamentals is going down the wrong path in learning C++.
    Code:
    #include <iostream>
    
    int main()
    {
       char *a;
       cin >> a[0];
    }
    Do you know what is wrong with this code? From what I see from your code, this is what you're doing.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 1st, 2013 at 10:39 PM.

  3. #3
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    Quote Originally Posted by Paul McKenzie View Post
    What is this?
    Code:
    #include <iostream>#include <string>
    You should fix the above so that you have one #include per line.
    You declared a pointer, and it points to junk. You cannot use it until you point that pointer somewhere valid. Where do you take that char* and point it to a valid character?
    Code:
      cin >> a.Name[0];
    What is that line above supposed to do? What is Name[0]? Is it that char* I mentioned? If so, again, where do you initially point that pointer to a valid memory address?

    To be more blunt, you using char* is no different than if you used an int*, double*, float*, etc. A char* is not a string -- it is a pointer, no different than any other pointer. If you are using pointers, that pointer must point to a valid memory location before you read or write to it. This is fundamental C++ knowledge, and by jumping into templates without knowing the fundamentals is going down the wrong path in learning C++.
    Code:
    #include <iostream>
    
    int main()
    {
       char *a;
       cin >> a[0];
    }
    Do you know what is wrong with this code? From what I see from your code, this is what you're doing.

    Regards,

    Paul McKenzie
    1st sorry about the include. isn't the 1st time that happens. but i only notice after put the post
    ok.. i'm having problems with char*
    1 question: why i can't use the string?(at least is more easy)
    i must learn, again, about pointers, but for C++
    i'm using char * for strings, like in C. is that the problem
    Last edited by Cambalinho; September 2nd, 2013 at 03:08 AM.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: about properties

    The problem with your using char * is that this is a pointer to some memory that contains characters. This pointer needs to be initialised to some valid memory of sufficient size to hold the number of required characters. This memory is usually obtained via new in c++ (or malloc/calloc for c). Nowhere in your code do you attempt to allocate this memory. You seem to just assume that 'its there'. The same applies to any pointer type (ie int*). Memory of the appropriate size must be allocated before that memory can be used.

    So in your code,

    Code:
    cin >> a.Name[0];
    Name needs to have had appropriately sized memory allocated to it before trying to read characters.

    To refresh your memory, have a look at

    http://www.learncpp.com/cpp-tutorial...style-strings/
    http://www.cplusplus.com/doc/tutorial/ntcs/
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    Quote Originally Posted by 2kaud View Post
    The problem with your using char * is that this is a pointer to some memory that contains characters. This pointer needs to be initialised to some valid memory of sufficient size to hold the number of required characters. This memory is usually obtained via new in c++ (or malloc/calloc for c). Nowhere in your code do you attempt to allocate this memory. You seem to just assume that 'its there'. The same applies to any pointer type (ie int*). Memory of the appropriate size must be allocated before that memory can be used.

    So in your code,

    Code:
    cin >> a.Name[0];
    Name needs to have had appropriately sized memory allocated to it before trying to read characters.

    To refresh your memory, have a look at

    http://www.learncpp.com/cpp-tutorial...style-strings/
    http://www.cplusplus.com/doc/tutorial/ntcs/
    my real problem is use char strings in arguments e returns
    i'm trying search a page for give more info

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: about properties

    Quote Originally Posted by Cambalinho View Post
    1 question: why i can't use the string?(at least is more easy)
    Because that code you have is faulty. That's the price you pay when you just get code from anywhere, don't know what it really does, and things don't work or compile.

    First, why are you using this roundabout way of doing something very simple? Why introduce a template when all you need is to call a setter() or getter() function? It looks like you're trying to create a problem on purpose. Do you think that the code you posted is easier to understand than simply calling setName(), getCount(), etc.?

    The place where you got this code -- do they have an example of using std::string? If not, then this is a reason why you should be using libraries from reputable sources such as boost. Code just gotten off the Internet from who-knows is likely never tested in a real environment or compiled using non-trivial, but popular C++ types such as std::string. Probably the author only tested on simple types such as int, double, etc. and never considered classes and templated types such as std::string.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 2nd, 2013 at 09:25 AM.

  7. #7
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    what i need is create properties without using get and set functions
    i have 1 code, but it's VS2010 code
    isn't compitble with GCC\G++ code
    why i'm doing these? because then is more easy to translate my language to C++

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: about properties

    Quote Originally Posted by Cambalinho View Post
    what i need is create properties without using get and set functions
    i have 1 code, but it's VS2010 code
    isn't compitble with GCC\G++ code
    why i'm doing these? because then is more easy to translate my language to C++
    If it's more easier, why are you having so many problems?

    The issue is this -- there is no way to "map" one language to another language on a line-by-line basis. That is what you're trying to do, and it can't be done. If a language does things one way, and another language does things another way, then it's your job to find out a way that the "destination" language does things.

    You're taking C++ and trying to make it do things syntactically it wasn't designed for. If translation from your language to C++ requires you to write a module to generate the proper C++ getter and setter functions, then so be it. What you're trying to do is make C++ look like your language, and that is not the goal of what a language translation program should be geared towards.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    Quote Originally Posted by Paul McKenzie View Post
    If it's more easier, why are you having so many problems?

    The issue is this -- there is no way to "map" one language to another language on a line-by-line basis. That is what you're trying to do, and it can't be done. If a language does things one way, and another language does things another way, then it's your job to find out a way that the "destination" language does things.

    You're taking C++ and trying to make it do things syntactically it wasn't designed for. If translation from your language to C++ requires you to write a module to generate the proper C++ getter and setter functions, then so be it. What you're trying to do is make C++ look like your language, and that is not the goal of what a language translation program should be geared towards.

    Regards,

    Paul McKenzie
    i understand what you mean but i belive theres is 1 way for create properties in C++
    (i can convert my own properties(my language) to set\get c++ functions, but i don't give up)
    i will continue search more

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: about properties

    Quote Originally Posted by Cambalinho View Post
    i understand what you mean but i belive theres is 1 way for create properties in C++
    There is no such thing as "properties" in C++. That is what you fail to understand.

    Unless you're a C++ expert (enough to never ask a question on CodeGuru) would you want to make C++ code look like something else. For example, boost::spirit makes C++ look like compiler production rules, but again, these are experts in C++ that know exactly what they're doing. If you're not an expert in C++, then all you're doing is cobbling together code you picked up from the Internet, and not know if it works, side-effects, whether there are issues, etc.

    Regards,

    Paul McKenzie

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: about properties

    Trying to implement 'properties' in c++ has been tried - and failed - before. See http://forums.codeguru.com/showthrea...73#post2117673
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  12. #12
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    finally i found 1 code that works:

    properties.h:

    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
            >;
        };
    }
    heres how use it:
    Code:
    #include <iostream>
    #include <string>
    #include <conio.h>
    #include "properties.h"
    
    using namespace std;
    
    class test
    {
        public:
        properties::DefaultProperty<int> age;
        properties::DefaultProperty<string> Name;
    };
    
    int main()
    {
        test b;
        string name;
        cin >> b.age;
        cin >> name;
        b.Name=name;
        cout << b.age << name;
        getch();
        return 0;
    }
    by some reason i only can use numeric types(tested now) in cin and cout, but for string we use another variables
    i hope you enjoy
    thanks for all
    Last edited by Cambalinho; September 2nd, 2013 at 11:57 AM.

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: about properties

    Quote Originally Posted by Cambalinho View Post
    finally i found 1 code that works:
    The problem is not std::string.

    The problem is that you did not overload the DefaultProperty class for operator >> or operator <<.

    The bottom line is that if you're going to use operator >> and <<, you need to make sure that whatever you place on the right side of >> and << is properly overloaded for I/O streaming, otherwise you have unexpected behaviour. Your property classes as they exist are not designed or were tested thoroughly for streaming. In other words, your code using operator >> for std::string is no different than this:
    Code:
    #include <iostream>
    
    struct foo
    {
    };
    
    using namespace std;
    int main()
    {
      foo f;
      cin >> f;  // same error -- no operator >>.
    }
    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 2nd, 2013 at 03:46 PM.

  14. #14
    Join Date
    Apr 2009
    Posts
    1,355

    Re: about properties

    Quote Originally Posted by Paul McKenzie View Post
    The problem is not std::string.

    The problem is that you did not overload the DefaultProperty class for operator >> or operator <<.

    The bottom line is that if you're going to use operator >> and <<, you need to make sure that whatever you place on the right side of >> and << is properly overloaded for I/O streaming, otherwise you have unexpected behaviour. Your property classes as they exist are not designed or were tested thoroughly for streaming. In other words, your code using operator >> for std::string is no different than this:
    Code:
    #include <iostream>
    
    struct foo
    {
    };
    
    using namespace std;
    int main()
    {
      foo f;
      cin >> f;  // same error -- no operator >>.
    }
    Regards,

    Paul McKenzie
    thanks for the feedback. maybe, in time, i can make my own code
    thanks for all

  15. #15
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: about properties

    The big question I have about all of this is - why??

    Your class test has the class variables public so that any user of this class can set/get the contents of these variables at will (ok with a nod towards the restrictions) but basically these are public class variables.

    The whole point of having private class variables and public getter/setter functions is to separate the underlying representation of the data with the public use of that data. So if, at a later date, it is required to change the underlying private data representation, this can be done without making changes to the public interface. Indeed, users of the class need never know that the underlying data representation has changed.

    In this case, if the test class data representation is changed, then all the code that uses that data has to be changed as well! Take a simple example. In class test you are storing the age as an integer. What about later if you want to store the age as say the number of days since 1900? As age is public, all uses of age have to be found and changed. Using class get/set functions GetAge(..) and SetAge(..) just these two functions would need to be changed to accomodate the data representation change.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured