繁体   English   中英

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

[英]Is there a Perl script to implement C++ Class get/set member functions?

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

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

虽然它没有直接回答您的问题,但您可能会发现生成的代码对于管理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

这是代码:

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

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!";
        }
    }
};

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

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

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

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

由于大多数C ++私有成员不应该通过Get / Set样式函数访问,这似乎是一个坏主意。

有关其原因的简单示例,请考虑C ++ std :: string类。 它的私人成员可能看起来像这样(确切的实现并不重要):

private:
   int last, len;
   char * data;

你认为为那些提供获取/设置成员是否有意义?

我无法帮助您了解该特定脚本的位置。 但是,有很多代码生成工具。 您甚至可能已经将所需内容作为IDE的一部分。 有关如何,为什么以及是否使用代码生成工具的更多辩论/输入,您可以查看此stackoverflow问题 我喜欢这个问题的接受答案。

我知道有一个程序员使用Perl来扩充预处理器该项目的最新版本 )。 基本的想法是你会决定一些约定来告诉你的Perl脚本何时生成一个getter或setter:

struct My_struct {
    //set
    //get
    int x;

    int y;

    //get
    int z;
};

给定这样的代码,我可以编写一个脚本来查找由成员变量声明之前的行上的注释“get”或“set”组成的注释行,然后用简单的setter / getter替换它们。 在上面的例子中,我将在关联的成员变量定义之后生成void set_x(int i),int get_x()和int get_z()。

警告:不要使用s ///就地执行此操作。 相反,单独扫描每一行,如果你找到一个合适的注释行,将“我需要一个getter / setter”的东西推到一个堆栈上,那么当你看到相关的成员变量时,弹出堆栈并生成代码。

细节中有一些恶魔,但总的来说就是这个想法。

您希望脚本不加选择地为所有私有成员生成get / set函数吗? 那不是一个非常有用的剧本; 你可能不会在谷歌找到它。 如果您希望能够以某种方式标记您的成员变量并为您自动生成getter和/或setter骨架,那么IDE宏似乎更合适。 试试谷歌吧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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