Is it possible in C++ to define several methods at once?

Sorry for the confusing title of this question, but I can’t think of an exact way to word it. I have a very long class with hundreds of similar methods and I am trying to find a way to construct it without so many lines of code and so many DRY violations. Each time I add a new property to my class I have to write two methods and update the copy function. There are already over 80 properties.

Currently this class is written in Java but I was wondering if it were written in C++ if it could be done more efficiently. I think it can be done using preprocessor x-macros like described in wikipedia here but I am not a fan of macros and would prefer to do it using the language itself if possible.

Here is a simplified snippet of my Java class:

class InMemoryPerson implements Person {
    private HashMap<String,Object> values = new HashMap<String,Object>();

    public InMemoryPerson copyFrom(Person p) {
        setName(p.getName());
        // more code to copy all the properties...
    }

    public void setName(String name) {
        values.put("name",name);
    }

    public String getName() {
        return (String)map.get("name");
    }

    // many more methods for all the different properties...
    // each method may have a different type
}

16

In C++ this is possible to do, using old style C macros.

// method is get/set method suffix
// name is the key in hash table
#define POINTER_PROPERTY(type,method,name) 
        type get##method(){return (type)_pointer_map[name];} 
        void set##method(type value){_pointer_map[name]=value;}

class InMemoryPerson : Person {
public:
    POINTER_PROPERTY(char *,Name,"name")

private:
    std::map<const char *,void *> _pointer_map;
};

Value types would have to be handled by different macro and (easiest way) by different hash for each type. Not sure though this code is more readable and manageable than 80 different get/set functions.

1

In c++ it should be quite simple. Throw out setters and getters, and member variables, and use default copy constructors to copy objects of this class. Something like this :

struct Person
{
    Person() : name("default name")
    {}

    std::string name;
    // etc
};

Person a;
// set fields of person a
Person b;
// set fields of person b
b = a;

7

This isn’t really an answer because of the following constraint from a comment…

Because I am implementing an interface this is not possible, there are several other implementations and my class must be compatible with the interface.

However, it might be an answer for someone else, so…

One option is to provide one getter and setter for each type and to use a parameter to identify which property. I can think of two ways to handle this…

  • Use an enumerate to provide all your property names, and store those properties in an array.

  • Use a separate struct to define all the member data, possibly as a public member of your class. Store the properties using in a private instance of that struct inside your class. Pass member pointers to your getters and setters to identify the property.

Either way allows the getters and setters to handle particular properties specially if needed. The member pointer method is only really mentioned for completeness, though – I’d prefer the enumerate method.

Once you can identify which property using a parameter, you still need different getters and setters for each property datatype. This can be avoided by specifying your getter and setter as member template functions. You still need some checks, though, to ensure that the property for the current call has the correct type. This is actually easier if you used the member pointer approach (the template can require that the member type for the member pointer matches the get/set type) though you’ll probably get other problems later.

The most obvious case where something like this is justified is if you’re developing a RAD-style tool.

The need for updating the copy function can be avoided by using default copy ctors, as @BЈовић has pointed out. For getters and setters, however, I would bite the bullet and use X-macros (if you don’t want to write an external code generator for this).

Whatever you do, you need a place where you associate the hash key "name" with the associated data type String and the corresponding getter/setter names (the names of these methods may follow a strict convention, but AFAIK there is no easy uppercase/lowercase conversion within the preprocessor). So defining that list using X-macros will at least give you a very compact and easy-to-extend solution (EDIT: see @petrch’s post for an example).

There was a three-part series on Embedded.com about X-macros, that gives a cleaner result than what the Wikipedia article describes.

#define EXPAND_AS_ENUMERATION(a,b) a,
#define EXPAND_AS_JUMPTABLE(a,b) b, 
#define STATE_TABLE(ENTRY)     
        ENTRY(STATE_0, func_0) 
        ENTRY(STATE_1, func_1) 
        ENTRY(STATE_2, func_2) 
        ...                    
        ENTRY(STATE_X, func_X)

/* declare an enumeration of state codes */ 
enum{
    STATE_TABLE(EXPAND_AS_ENUMERATION)
    NUM_STATES
}

/* declare a table of function pointers */ 
p_func_t jumptable[NUM_STATES] = {
    STATE_TABLE(EXPAND_AS_JUMPTABLE)
}:

Here’s Part 1.

Here’s Part 2.

They blew the in-article link to Part 3. Here it is.

They require you to create a free account and profile, so they can spam you, if you want to read more than 2 articles per day. (BOO! HISS!) The 2-article limit is a fairly recent change to what used to be a really good site.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật