How much functionality is “acceptable” for a C++ s

2019-03-18 04:05发布

My first post so please go easy on me!

I know that there's no real difference between structs and classes in C++, but a lot of people including me use a struct or class to show intent - structs for grouping "plain old data" and classes for encapsulated data that has meaningful operations.

Now, that's fine but at what point do you start to think that something isn't just a struct anymore and should become a class?

Things I think are reasonable for structs to have:

  1. constructors with simple initialisation code only.
  2. serialization code such as stream insertion / extraction operators.

Things I'm not so sure about, but would probably do:

  1. comparison operators
  2. Simple transformation functions - for example byteswapping all the members after receiving data from an external source.

I don't think structs should have:

  1. dynamic memory allocation.
  2. destructor.
  3. complex member functions.

Where do the boundaries lie???

Also, is it reasonable to have class instances as members of a struct? e.g.

class C {private: int hiddenData; public: void DoSomething();};

struct S {int a; float b; C c; };

S s; s.c.DoSomething();

Remember, I'm not on about what you CAN do with C++, I'm interested in what you SHOULD do when designing good software.

Thoughts?

标签: c++ oop struct
19条回答
ゆ 、 Hurt°
2楼-- · 2019-03-18 04:44

I think there are three major, coherent schools of thought:

  1. People that don't care either way and use struct and class interchangeably.
  2. People that use structs only to represent small POD.
  3. People who use structs as records.

I can't make a conclusive argument for either of these strategies. I tend to follow path 2 but I also use structs for non-POD types when I see it fitting, especially for function objects (even if these may not fulfil POD requirements).

(Incidentally, the C++ FAQ lite has a pretty good definition of POD).

EDIT I didn't touch template metaprogramming techniques, such as using struct for placeholders (type tags) or to implement metafunctions. I guess there's absolutely no controversy in these cases: since they never contain methods (or even data), always use struct).

查看更多
叼着烟拽天下
3楼-- · 2019-03-18 04:44

Generally, I use class whenever I need to use access specifiers. This has the effect that most of my top-level stuff remain as classes, while the rare POD collections and my not-so-rare inner-class pimpls are usually structs.

查看更多
家丑人穷心不美
4楼-- · 2019-03-18 04:47

The only methods I like to put on structs are property-type methods, simple transforms (and, if appropriate for the type, operators), and non-default constructors.

Properties

For instance, I might define a RECT struct as below:

typedef struct tagRECT{
    int left;
    int top;
    int right;
    int bottom;

    int get_width(){return right - left;}
    int get_height(){return bottom - top;}
    int set_width(int width){right = left + width; return width;}
    int set_height(int height){bottom = top + height; return height;}
} RECT, *PRECT;

The "set" methods return the new value to support assignment chaining in the case that the compiler supports properties as an extension.

Simple transforms

For POD types that store complex data, I might include methods that perform simple transformations on that data. An obvious example might be including Rotate, Scale, Shear, and Translate methods on a TransformationMatrix struct.

Operators

Really just an extension of the above, if operators make sense for the type, I will add them to a struct. This can be appropriate and necessary to maintain the atomicity of the object. An obvious example is standard arithmetic operators on a Complex struct.

Constructors

I prefer not to have a default constructor on my structs. I don't want to allocate an array of PODs and suffer the invocation of a thousand (or whatever) default initializations. If memset initialization won't suffice, I'll provide an Initialize method.

I will, however, provide a non-default constructor on structs. This is especially useful when one or more fields can be inferred from partial construction.

查看更多
【Aperson】
5楼-- · 2019-03-18 04:49

I use struct whenever I want to use data member as interface of the object. I'd change the struct to a class, whenever there is a need to add a private section.

查看更多
ら.Afraid
6楼-- · 2019-03-18 04:50

If there's accesser methods for the data members then it's a class.

If you have direct access to the data and can modify it at will, it's a struct.

There's no reason a struct shouldn't have constructors, comparison operators, etc.

查看更多
混吃等死
7楼-- · 2019-03-18 04:51

I'll add a very few methods to a struct, as a matter of convenience, only if I'm actually using them. Of course all of them are public. If I need any more than this, it immediately gets converted to a class.

  1. A default constructor, to initialize the data members to known values.
  2. A constructor with one parameter for each member.
  3. operator<, for easy inclusion in sets and maps.
  4. operator==.
查看更多
登录 后发表回答