A property similar to functions in C ++?

My use is quite complicated. I have a group of objects, and all of them are passed using ptr (no reference or value, unless this is an enumeration that is byte). At a certain point in time, I like to call CheckMembers (), which will check if each element has been set or is zero. By default, I cannot make everything null, because I don’t know if it set its value to null or if it still has the value null bc I havent touch it c ctor.

To assign a variable, I still need the syntax as normal var = p; var->member = new Type;. I generate all classes / members. So my question is, how can I implement a property similar to a function, where can I determine if a value has been set or remains by default?

I think maybe I can use C ++ with CLR / .NET http://msdn.microsoft.com/en-us/library/z974bes2.aspx , but I have never used it before and I don’t know how well it will work and what might break in my C ++ prj (it uses rtti, templates, etc.).

+2
source share
3 answers

Reality (edit): , . . , , . checkMembers() , . , .

#include <iostream>

using namespace std;

class PropertyBase
{
    public:
        int * counter;
        bool is_set;
};

template <typename T>
class Property : public PropertyBase
{
    public:
        T* ptr;
        T* operator=(T* src)
        {
            ptr = src;
            if (!is_set) { (*counter)--; is_set = true; }
            return ptr;
        }
        T* operator->() { return ptr; }
        ~Property() { delete ptr; }
};

class Base
{
    private:
        int counter;
    protected:
        void TrackProperty(PropertyBase& p)
        {
            p.counter = &counter;
            counter++;
        }
    public:
        bool checkMembers() { return (counter == 0); }
};

class OtherObject : public Base { }; // just as an example

class MyObject : public Base
{
    public:
        Property<OtherObject> x;
        Property<OtherObject> y;
        MyObject();
};

MyObject::MyObject()
{
    TrackProperty(x);
    TrackProperty(y);
}

int main(int argc, char * argv[])
{
    MyObject * object1 = new MyObject();
    MyObject * object2 = new MyObject();

    object1->x = new OtherObject();
    object1->y = new OtherObject();

    cout << object1->checkMembers() << endl; // true
    cout << object2->checkMembers() << endl; // false

    delete object1;
    delete object2;

    return 0;
}
+6

. , :

#include <iostream>

template<typename T, typename OuterClass>
class Property
{
public:
    typedef void (OuterClass::*setter)(const T &value);
    typedef T &value_type;
    typedef const T &const_type;
private:
    setter set_;
    T &ref_;
    OuterClass *parent_;
public:
    operator value_type() { return ref_; }
    operator const_type() const { return ref_; }

    Property<T, OuterClass> &operator=(const T &value)
    {
        (parent_->*set_)(value);
        return *this;
    }

    Property(T &ref, OuterClass *parent, setter setfunc)
        : set_(setfunc), ref_(ref), parent_(parent)
    { }
};


struct demo {
    private:
        int val_p;
        void set_val(const int &newval) {
            std::cout << "New value: " << newval << std::endl;
            val_p = newval;
        }

    public:
        Property<int, demo> val;

        demo()
            : val(val_p, this, &demo::set_val)
        { }
};

int main() {
    demo d;
    d.val = 42;
    std::cout << "Value is: " << d.val << std::endl;
    return 0;
}

( 4 * sizeof(void*) ) - :

#include <iostream>


template<typename T, typename ParentType, typename AccessTraits>
class Property
{
private:
    ParentType *get_parent()
    {
        return (ParentType *)((char *)this - AccessTraits::get_offset());
    }
public:
    operator T &() { return AccessTraits::get(get_parent()); }
    operator T() { return AccessTraits::get(get_parent()); }
    operator const T &() { return AccessTraits::get(get_parent()); }
    Property &operator =(const T &value) {
        AccessTraits::set(get_parent(), value);
        return *this;
    }
};

#define DECL_PROPERTY(ClassName, ValueType, MemberName, TraitsName) \
    struct MemberName##__Detail : public TraitsName { \
        static ptrdiff_t get_offset() { return offsetof(ClassName, MemberName); }; \
    }; \
    Property<ValueType, ClassName, MemberName##__Detail> MemberName;

struct demo {
    private:
        int val_;

        struct AccessTraits {
            static int get(demo *parent) {
                return parent->val_;
            }

            static void set(demo *parent, int newval) {
                std::cout << "New value: " << newval << std::endl;
                parent->val_ = newval;
            }
        };
    public:
        DECL_PROPERTY(demo, int, val, AccessTraits)

        demo()
        { val_ = 0; }
};

int main() {
    demo d;
    d.val = 42;
    std::cout << "Value is: " << (int)d.val << std::endl;
    return 0;
}

; offsetof() ( -POD-). this -.

, , - operator* operator-> .., .

+6

. , .

#include <iostream>
#include <cassert>

using namespace std;

template <class T>
class Property
{
    bool isSet;
    T v;
    Property(Property&p) { }
public:
    Property() { isSet=0; }
    T operator=(T src) { v = src; isSet = 1; return v; }
    operator T() const { assert(isSet); return v; }
    bool is_set() { return isSet; }
};

class SomeType  {};
enum  SomeType2 { none, a, b};
class MyObject
{
public:
    Property<SomeType*> x;
    Property<SomeType2> y;
    //This should be generated. //Consider generating ((T)x)->checkMembers() when type is a pointer
    bool checkMembers() { return x.is_set() && y.is_set(); }
};

int main(int argc, char * argv[])
{
    MyObject* p = new MyObject();
    p->x = new SomeType;
    cout << p->checkMembers() << endl; // false
    p->y = a;
    cout << p->checkMembers() << endl; // true
    delete p->x;
    delete p;
}
+2

All Articles