回收成员功能而无需继承

时间:2014-10-22 02:48:01

标签: c++

Wikipedia上为Properties提供了一个有趣的模板。

这个模板提供了一些有趣的东西,因为它允许围绕成员访问提供逻辑。在此基础上,我们可以轻松地构建这样的东西:

struct Ranged { 
  ranged_property<float,0,1> unit_property; 
}; 

强制unit_property的范围在[0,1]范围内。

我们如何提供类似的功能取决于托管类&#39;成员?例如:

struct AdjustableRanged { 
  float max; 
  ranged_property<float,0,max> influenceable_property; 
};

influenceable_property的范围受max的影响。请记住,目标是将这种模板循环到许多不同的类中。相关概念是mixins和decorator。

可以用宏来完成......但我觉得必须是一个更好的更惯用的C ++解决方案。


编辑添加:我认为这可以通过在ranged_property模板中保存对成员的引用来完成......但这似乎完全浪费了空间,实际上是一个常量值;的 ETA ; const引用实际上可以达到目的,但是,我需要进行调查。

1 个答案:

答案 0 :(得分:2)

继续我们在评论中的讨论,似乎可以使用像这样的指针到成员模板参数来实现功能(但请参阅下面的注意事项):

#include <iostream>

template<typename C, typename T, T C::*m>
struct PrintMember {
    C& obj;
    PrintMember(C& obj) : obj(obj) {};
    void print() { std::cout << "Member of containing class: " << obj.*m << std::endl; };
};

struct TestClass {
    int data;
    PrintMember<TestClass, int, &TestClass::data> pm;
    TestClass() : pm(*this){};
};

int main()
{
    TestClass tc;
    tc.data = 5;
    tc.pm.print();
}

这仅表明可以访问包含对象的成员。这种方法有一些事情无法解决:

  • 如果您真的只想访问一个成员,那就不值得,因为您必须在PrintMember成员中保存对*this的引用,能够取消引用指向成员的指针。因此,它实际上并没有解决必须存储引用的问题。您也可以在构造函数中传递对成员变量本身的引用。但是,如果您需要访问多个成员,则只允许存储一个引用(到*this)并仍然访问所有成员。

  • 指定PrintMember的模板参数并在构造函数中使用PrintMember初始化*this成员变量非常繁琐。也许,一些聪明的模板参数演绎可以在这里帮助,但我还没有尝试过,我甚至不确定它会变得更简单...

在某些特殊情况下,可能会有肮脏的方式来访问&#34;这个&#34;封闭类的指针没有明确保存,就像在this answer中使用offsetof的答案一样,但我的感觉告诉我你想要一些便携而且不那么脆弱的东西......