Ok to provide constructor + trivial operators for behaviorless aggregates?
This is a follow-up question to 2043381.
Consider the following:
struct DataBundle
{
std::string name;
int age;
DataBundle() : age(0) {}
DataBundle(const std::string& name, int age)
: name(name), age(age) {}
void swap(DataBundle& 开发者_StackOverflowrhs)
{name.swap(rhs.name); std::swap(age, rhs.age);}
DataBundle& operator=(DataBundle rhs) {swap(rhs); return *this;}
bool operator==(const DataBundle& rhs) const
{return (name == rhs.name) && (age == rhs.age);}
bool operator!=(const DataBundle& rhs) const {return !(*this == rhs);}
}
In the spirit of rule #41 of C++ Coding Standards (see related article), would this still be considered a behaviorless aggregate? I don't like writing "dumb" classes with mostly getters/setters, and would rather use an all-public struct to indicate it's just a "bundle-o-data". But in the above example, am I at the point where I should make DataBundle a class with getters/setters?
No, no need for getters and setters yet. It is still a plain data structure where no methods implement actions modifying the data structure - compare, assign, swap are no 'behaviour' here, they're stub needed by the language to perform basic operations and to make the data structure actually usable.
You need to decide whether there are any dependencies or invariants to be hold between the fields of structure. If they exist (or may exist in future), use getters or setters to ensure them (i.e. adjust attribute a if attribute b is changed). If not, declare everything public. name
and age
are decoupled properties of a human being, I don't think accessors are really necessary here. Of course it's a matter of taste.
Well it's not an aggregate in C++ Standard terms - see section 8.5.1 Aggregates:
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).
精彩评论