【问题标题】:C++ property template for classes without standard constructor没有标准构造函数的类的 C++ 属性模板
【发布时间】:2019-12-14 18:34:31
【问题描述】:

我想实现一个完全不使用 C 宏的 C# 属性的 C++ 等效项。我创建了一个模板,它基本上以get()set() 的更好的方式设置或检索内部值。在构造函数中还有两个std::function 类型的参数,我可以在其中覆盖默认的getter 和setter 方法。

template<typename T>
class Property
{
public:

  Property(T initialValue, std::function<void(T&)> setter, std::function<T&()> getter)
  {
    Value = initialValue;
    Setter = setter;
    Getter = getter;
  }

  ~Property()
  {
  }

  void operator =(T value)
  {
    if(Setter == nullptr)
    {
      Set(value);
    }
    else
    {
      Setter(value);
    }
  }

  T& operator ()()
  {
    if(Getter == nullptr)
    {
      return Get();
    }
    else
    {
      return Getter();
    }
  }

  void Set(T& value)
  {
    Value = value;
  }

  T& Get()
  {
    return Value;
  }

private:

  T Value;

  std::function<void(T&)> Setter = nullptr;
  std::function<T&()> Getter = nullptr;

}

以下代码 sn-p 显示了int 类型的Property 对象的定义。 (getter 和 setter 被 lambda 表达式覆盖。)

Property<int> prop = Property<int>(0,

  [&](int& val)
  {
    // some code inside the overridden setter

    prop.Set(val);
  },

  [&]() -> int&
  {
    // some code inside the overridden getter

    return prop.Get();
  });

Getter 和 setter 的调用方式如下:

int foo = prop();

prop = foo;

我认为一切都会好起来的,而且确实如此。在我尝试将一个不包含标准构造函数的类作为模板类型传递之前,它确实如此。我知道,声明 T Value; 会导致问题,但我想不出任何替代方案或解决方法。

也许,您知道如何使这个概念适用于基本类型、类和没有标准构造函数的类。

【问题讨论】:

    标签: c++ class templates constructor properties


    【解决方案1】:

    IMO,这门课是个坏主意。

    所有这些std::functions 可能会增加合理的开销(在性能和内存方面)。


    也就是说,这是答案:

    未在Property 的构造函数的成员初始化列表中指定Value 会导致Value 被默认初始化(并且然后 分配一个值)。

    解决方法是在成员初始化器列表中对其进行初始化,而不是在构造函数体中赋值给它:

    Property(T initialValue, std::function<void(T&)> setter, std::function<T&()> getter)
        : Value(initialValue)
    {
        Setter = setter;
        Getter = getter;
    }
    

    SetterGetter 也做同样的事情是个好主意。


    此外,Getoperator() 不得返回非 const 引用(按值返回或通过 const 引用返回)。在此处返回非常量引用允许用户绕过指定的设置器并直接更改值。此外,您应该使Getoperator() const

    operator=Setstd::function&lt;...&gt; Setter 应通过 const 引用获取新值。

    您应该将T Value 的引用传递给Setter,并将const 的引用作为参数传递给Getter,而不是在lambda 中捕获对属性的引用。如果引用被移动,捕获引用会使您的课程中断。

    Getter 应该按值返回(允许它返回修改后的Value),或者返回void(如果它的唯一目的是在返回值时调用函数,而不能修改什么是返回)。

    【讨论】:

    • std::function 的开销之后,std::function 的控制块是巨大的。如果你为一个类的每个属性分配几个,然后用那个类的实例填充一个向量,你会很糟糕。我曾经尝试创建一个类,而不是方法有一堆成员,这些成员基本上是std::function,并且构造函数会将 lambdas 分配给它们以使它们具有我想要的逻辑,因此它们像实际方法一样工作。虽然它起作用了,但如果像一个理智的人一样实施,它在所有操作上的速度比课堂慢 5-15 倍。
    猜你喜欢
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 2011-07-15
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多