简体   繁体   中英

Member function pointer as constructor parameter

I have a Property Class that i use to set up getter and setter properties in classes. It works but to use it i have to setup the property with a public variable and in the constructor call 3 methods, 1 function to set the class instance, 1 to set the setter, and one to set the getter.

class PropTest
{
private:
    int m_nCount;

    int getCount()
    {
        return m_nCount;
    }
    void setCount(int nCount)
    {
        m_nCount = nCount;
    }

public:
    PropTest()
    {
        Count.setObject(this);
        Count.setSetter(&PropTest::setCount);
        Count.setGetter(&PropTest::getCount);
    }

    Property<PropTest, int> Count = Property<PropTest, int>(PropertyPermission::READ | PropertyPermission::WRITE);
};

That works fine but im trying to get it all down to one line...

Property<PropTest, int> Count = Property<PropTest, int>(this, &PropTest::getCount, &PropTest::setCount, PropertyPermission::READ | PropertyPermission::WRITE);

But when i add the new costructor to the class and try to compile i get: error C2276: '&' : illegal operation on bound member function expression

The new constructor is:

template <class Class, typename Return> !!This template is for the whole class not the function. Just figured you needed to see it.

Property(Class* pObject, Return(Class::*pGetter)(), void (Class::*pSetter)(Return pValue), const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)

Adding the instance worked right away, but the getter and setter parameters are whats causing the error. But the same setup when used in the setGetter and setSetter methods compile and work fine.

Thanks...

EDIT

Property<PropTest, int> Count{ this, &PropTest::getCount, &PropTest::setCount, PropertyPermission::READ | PropertyPermission::WRITE };

Is the line causing the error...

Property Class-

static const enum PropertyPermission
{
    READ = (1 << 0),
    WRITE = (1 << 1)
};

template <class Class, typename Return>
class Property
{
private:
    Class* _object;
    Return(Class::*_getter)();
    void (Class::*_setter)(Return value);

public:
    Property(const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)
    {
        _getter = nullptr;
        _object = nullptr;
        _setter = nullptr;
        permission = pPropertyPermission;
    }
    Property(Class* pObject, const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)
    {
        _getter = nullptr;
        _object = pObject;
        _setter = nullptr;
        permission = pPropertyPermission;
    }
    Property(Class* pObject, Return(Class::*pGetter)(), void (Class::*pSetter)(Return pValue), const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)
    {
        _getter = nullptr;
        _object = pObject;
        _setter = nullptr;
        permission = pPropertyPermission;
    }

    operator Return()
    {
        //test for object and getter != null
        if (!(permission & PropertyPermission::READ))
    {
        //throw write only
    }
    return (_object->*_getter)();
    }

    Return operator =(const Return& pValue)
    {
        //test for object and setter != null
        if (!(permission & PropertyPermission::WRITE))
        {
            //throw read only
        }
        (_object->*_setter)(pValue);
        return pValue;
    }

    void setGetter(Return(Class::*pGetter)())
    {
        //test for object != null
        _getter = pGetter;
    }
    void setObject(Class* pObject)
    {
        _object = pObject;
    }
    void setSetter(void (Class::*pSetter)(Return pValue))
    {
        //test for object != null
        _setter = pSetter;
    }

    int permission;
};

Testing-

int main(int pArgumentLength, char* pArguments[])
{
    int i = 5;
    int j = 0;
    PropTest* test = new PropTest();
    test->Count = i;
    j = test->Count;
    std::cout << test->Count << std::endl;
    std::cout << j << std::endl;
    delete test;
}

EDIT

I use visual studios... When I turned of -Treat warnings as errors- it compiled but had an exception:

Unhandled exception at 0x7445C9F5 in TestBed.exe: 0xC0000005: Access violation executing location 0x00000000.

There were 2 warnings:

Warning 2   warning C4100: 'pSetter' : unreferenced formal parameter ...\testbed\program.cpp    58  1   TestBed

Warning 3   warning C4100: 'pGetter' : unreferenced formal parameter    ...\testbed\program.cpp 58  1   TestBed

Line 58 is the constructor:

Property(Class* pObject, Return(Class::*pGetter)(), void (Class::*pSetter)(Return pValue), const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)

SOLUTION

So this line caused the error:

Property<PropTest, int> Count = Property<PropTest, int>(this, &PropTest::getCount, &PropTest::setCount, PropertyPermission::READ | PropertyPermission::WRITE);

Using this instead compiles and runs fine: (Kerrek SB)

Property<PropTest, int> Count{ this, &PropTest::getCount, &PropTest::setCount, PropertyPermission::READ | PropertyPermission::WRITE };

But I don't know why...

Thanks for all the replies.

In your Property class implementation you never set your pointer members values :

Property(Class* pObject, Return(Class::*pGetter)(), void (Class::*pSetter)(Return pValue), const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)
{
    _getter = nullptr;
    _object = pObject;
    _setter = nullptr;
    permission = pPropertyPermission;
}

Should be changed to:

Property(Class* pObject, Return(Class::*pGetter)(), void (Class::*pSetter)(Return pValue), const int pPropertyPermission = PropertyPermission::READ | PropertyPermission::WRITE)
{
    _getter = pGetter;
    _object = pObject;
    _setter = pSetter;
    permission = pPropertyPermission;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM