首页 > 解决方案 > 结构类型的c ++属性实现wrt getter不能自动转换?

问题描述

我试图在 C++ 上实现 Property,这是我的代码:Property.hpp

#ifndef __VIOLET_PROPERTY_H__
#define __VIOLET_PROPERTY_H__

class IProperty
{
protected:
    virtual void init_properties() = 0;
};

#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;
    }

    //-- 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)(const 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 = operator 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;
    }

    //-- Cast the property class to the internal type --
    operator ValueType()
    {
        assert(m_cObject != NULL);
        assert(Get != NULL);
        return (m_cObject->*Get)();
    }

private:
    //-- Pointer to the module that contains the property --
    Container* m_cObject;
    //-- Pointer to set member function --
    void (Container::* Set)(const ValueType& value);
    //-- Pointer to get member function --
    ValueType(Container::* Get)();
};

#endif

源.cpp

#include <iostream>
#include <assert.h>
#include "Property.hpp"
using namespace std;

struct B
{
    B(int _v) { value = _v; }
    int value = 0;

    operator int() {
        return value;
    }
};

class A
{
    B value = 10;
    void setValue(const B& _value)
    {
        value = _value.value;
    }
    B getValue()
    {
        return value;
    }
public:
    A() {
        Value.setContainer(this);
        Value.setter(&A::setValue);
        Value.getter(&A::getValue);
    }
    property<A, B, READ_WRITE> Value;
    operator B() {
        return value;
    }
};

int main()
{
    A a = A();
    B b = a.Value;
    int num = 1 + (B)a.Value + b;
    cout << num << endl;
}

我的问题是为什么我需要强制设置(B)a.Value不能使用隐式转换,就像1+a.Value 我已经为 getter 设置了转换函数一样,为什么我不能从中获取ValueType类型?

    operator ValueType()
    {
        assert(m_cObject != NULL);
        assert(Get != NULL);
        return (m_cObject->*Get)();
    }

但是,如果我无法实现它,是否意味着我将获得更多的显式转换成本?感谢任何帮助。

标签: c++propertiesgetter

解决方案


您有两个用户定义的转换:

  • a.Value是一个property<A,B,READ_WRITE>。它有一个用户定义的转换运算符到B.
  • B有一个用户定义的转换运算符到int.

它们不能形成所谓的隐式转换序列,因此您需要先显式转换a.ValueB。来自cppreference.com

隐式转换序列包含以下内容,按此顺序:

1) 零个或一个标准转换序列;

2) 零次或一次 用户自定义转换;

3) 零或一标准转换序列。


但是,如果我无法实现它,是否意味着我将获得更多的显式转换成本?

不,优化编译器将其转换为对封装整数的直接访问不会有任何问题。


但是,您可以使用转换运算符模板来获得所需的内容:

#include <iostream>
 
struct Inner {
    int value = 42;
    operator int() const {
        return value;
    }
};
 
struct Outer {
    Inner thing;
    template<typename T>
    operator T() const {
        return thing;  // One implicit conversion sequence here, 
                       // with one user defined conversion (from Inner to int)
    }
};
 
 
int main() {
    Outer b;
    int answer = b; // Another implicit conversion sequence here,
                    // with one user defined conversion (from Outer to int)
    std::cout << answer << std::endl;
}

在您身上使用类似的模板A会得到您想要的。


推荐阅读