-
September 1st, 2013, 02:57 PM
#1
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)
-
September 1st, 2013, 06:24 PM
#2
Re: about properties
Originally Posted by Cambalinho
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?
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.
-
September 2nd, 2013, 03:03 AM
#3
Re: about properties
Originally Posted by Paul McKenzie
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?
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.
-
September 2nd, 2013, 06:23 AM
#4
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,
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)
-
September 2nd, 2013, 09:15 AM
#5
Re: about properties
Originally Posted by 2kaud
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,
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
-
September 2nd, 2013, 09:17 AM
#6
Re: about properties
Originally Posted by Cambalinho
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.
-
September 2nd, 2013, 09:22 AM
#7
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++
-
September 2nd, 2013, 09:31 AM
#8
Re: about properties
Originally Posted by Cambalinho
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
-
September 2nd, 2013, 09:34 AM
#9
-
September 2nd, 2013, 09:44 AM
#10
Re: about properties
Originally Posted by Cambalinho
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
-
September 2nd, 2013, 09:54 AM
#11
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)
-
September 2nd, 2013, 11:49 AM
#12
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.
-
September 2nd, 2013, 03:08 PM
#13
Re: about properties
Originally Posted by Cambalinho
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.
-
September 2nd, 2013, 05:17 PM
#14
Re: about properties
Originally Posted by Paul McKenzie
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
-
September 3rd, 2013, 04:17 AM
#15
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)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|