Structs vs Classes
You are correct, a primary difference between struct and class in C++ is default access levels. Without an explicit access modifier, class members are private, and struct members public. Struct members can also be made private using an access modifier. Keep in mind; this also applies to inherited classes and structs.
As for a general recommendation: many use structs only for data and classes for everything with behavior [1]. In other words, structs for POD (Plain Old Data) types[2], this is a widespread practice. It does not mean you cannot have functionality related to accessing and setting data members, setting up constructors, destructors, etc. "If more functionality is required, a class is more appropriate. If in doubt, make it a class." Their guide also recommends structs instead of classes for functors and traits.
You have to keep in mind, aside from any technical upsides or downsides, there are other reasons to enforce specific practices and standards in a team, and on a project basis. As also mentioned in Google's style guide, we can add semantic meaning to the data structures we use. As a team member, I would want to know if structs have behavior or not. It would be nice to know, for instance, that all structs are just POD types.
The Joint Strike Fighter coding standard specifies, "A structure should be used to model an entity that does not require an invariant." While "A class should be used to model an entity that maintains an invariant." And that public and protected data should only be used in structs, not in classes. Their rationale for this is that a class can't control access to public members; hence, all data in a class should be private. Consider the needs of your project when deciding on coding standards.
Struct inheritance
When thinking about inheritance, you must consider what public inheritance means versus private inheritance. Keep in mind what access levels the new, derived one will have, and if it makes sense to inherit your structs. Struct members can be made private, if you inherit from this, the derived one will not have access to the base's private members.
struct base {
int public_data;
private:
int private_data;
};
struct derived : base {
derived() {
public_data = 1;
// private_data = 1; // no access, won't compile
}
};
In other words, inheritance might be considered more of a logical issue than an implementation one.
There is nothing, technically, fundamentally wrong with inheriting structs. It might be a benevolent practice, and it might, in some cases, be beneficial and make a lot of sense.
Keep in mind, in C++, structs can inherit from classes and vice versa.
See this question for more information on vtables: When is a vtable created in C++?
[1] https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes
[2] http://en.cppreference.com/w/cpp/concept/PODType