是否有一个Perl脚本来实现C++类的get/set成员函数?

nmu*_*ntz 3 c++ perl code-generation

我今天早上正在阅读每个程序员应该拥有的关于基本工具的实用程序员第3章,他们提到了代码生成工具.他们提到了一个用于C++程序的Perl脚本,它帮助自动化为私有数据成员实现get/set()成员函数的过程.

有谁知道这样的脚本以及在哪里找到它?我一直无法找到合适的谷歌关键字来找到它.

j_r*_*ker 9

虽然它没有直接回答您的问题,但您可能会发现生成的代码对于管理C++中的属性实际上是不必要的.以下模板代码将允许您方便地声明和使用属性:

// Declare your class containing a few properties
class my_class {
public:
    property<int> x;
    property<string> y;
    ...
};

...

my_class obj;
cout << obj.x();          // Get
obj.y("Hello, world!");   // Set
Run Code Online (Sandbox Code Playgroud)

这是代码:

// Utility template to choose the 2nd type if the 1st is void
template <typename T, typename U>
struct replace_void {
    typedef T type;
};

template <typename T>
struct replace_void<void, T> {
    typedef T type;
};

// Getter/setter template
template <typename T, typename D = void>
class property {
    typedef typename replace_void<D, property>::type derived_type;

    derived_type& derived() { return static_cast<derived_type&>(*this); }

public:
    property() {}   // May be safer to omit the default ctor
    explicit property(T const& v) : _v(v) {}
    property(property const& p) : _v(p._v) {}
    property& operator=(property const& p) { _v = p._v; return *this; }

    T operator()() const { return _v; }                 // Getter
    void operator()(T const& v) { derived().check(v); _v = v; }   // Setter

protected:
    // Default no-op check (derive to override)
    void check(T const& v) const { (void)v; //avoid unused variable warning}

private:
    T _v;
};
Run Code Online (Sandbox Code Playgroud)

check()是一个函数,用于测试分配的值是否有效.您可以在子类中覆盖它:

class nonnegative_int : public property<int, nonnegative_int> {
public:
    // Have to redeclare all relevant ctors unfortunately :(
    nonnegative_int(int v) : property<int, nonnegative_int>(v) {}

    void check(int const& v) const {
        if (v < 0) {
            throw "Yikes! A negative integer!";
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

你有它 - 外部生成的getter/setter函数的所有优点,没有任何混乱!:)

您可以选择check()返回bool指示有效性而不是抛出异常.并且您原则上可以添加类似的方法access(),用于捕获对该属性的读取引用.

编辑:正如Fooz先生在评论中指出的那样,类作者可以在不修改类的逻辑结构的情况下更改实现(例如,通过用property<int> x一对x()方法替换成员),尽管二进制兼容性丢失,因此用户需要无论何时进行此类更改,都要重新编译其客户端代码. 这种无痛地融入未来变化的能力实际上是人们首先使用getter/setter函数而不是公共成员的主要原因.

性能说明:因为我们使用CRTP来实现"编译时多态性",所以check()在子类中提供自己的虚拟调用开销没有任何虚拟调用开销,您无需声明它virtual.