Difference between struct and enum? - c++

I am newbie to C++, and want to understand what is the difference between saying
typedef enum stateUpdateReasonCode
{
a=1,
b=2,
c=3
} StateUpdateReasonCode;
and
struct StateUpdateReasonCode
{
a=1,
b=2,
c=3
};
What is difference between them ? Wy would we use one over another ?
Kind Regards

An enum and a struct are totally different concepts, fulfilling different purposes.
An enum lets you declare a series of identifiers for use in your code. The compiler replaces them with numbers for you. It's often useful for making your code more readable and maintainable, because you can use descriptive names without the performance penalty of string comparisons. It can also make the code less bug-prone because you don't have to keep writing in specific numbers everywhere, which could go wrong if a number changes.
A struct is a data structure. At its simplest, it contains zero or more pieces of data (variables or objects), grouped together so they can be stored, processed, or passed as a single unit. You can usually have multiple copies (or instances) of it. A struct can be a lot more complex though. It's actually exactly the same as a class, except that members are public by default instead of private. Like a class, a struct can have member functions and template parameters and so on.
One of the vital difference between structs and enums is that an enum doesn't exist at run-time. It's only for your benefit when you're read/writing the code. However, instances of structs (and classes) certainly can exist in memory at runtime.
From a coding standpoint, each identifier in an enum doesn't have its own type. Every member within a struct must have a type.

The first compiles, the second does not.
Your struct declaration is invalid. In plain C struct are so called record types, they contain a set of values (each with it's own type). In C++ this capability is expanded and a struct is basically equivalent to a class. The struct can now have base classes, member functions, access specifiers, conversion operators, operator overloads and so on.
An enum is an enumeration type: it describes a finite set of states. In C and C++ the fact that enum values are convertible to integers is more or less a leaking abstraction.
They are fundamentally different.

Struct
For a struct these values are defaults (only for C++ 11 onwards) for the data structure. A "struct" is a structure of data, for example:
struct Car
{
float enginesize = 0.0f;
char modelname[100];
};
You would assign these values after you've declared a variable of the type Car etc:
{
Car brum = {1.0f}; // Specify a a size: don't use default
Car zoom; // Will default to 0.0 as specified in the struct
}
Without a default value it will undefined (something random).
Enum
An enumeration, however, is renamed numeric values: it's a very handy way of naming numeric constants. e.g.
enum EngineType
{
Petrol,
Diesel,
Electric,
LPG = 34 // NB assigning values is optional
};

enum work like the constants where you want to specify the the value with a word. Like for the days of week one want that sun = 0, mon = 1 and so on. In this case enum can be used.
struct is totally different from the enum. It can be seen analogues to the class in c++ or any other programming language. structure is a user defined data type which can be used to store the info. Like in address different fields can be there street , zip code etc.
the first one compiles as it stores the value of an enum and second one does not as struct variable data members values can be assigned by creating a struct variable.

Related

Extending struct member with another struct

Instead of making a new question I will edit this one by completely erasing the previous one, hopefully making it less confusing.
Wall of text.
I have a basic struct that has some basic values, such as image width, height and x and y positions, like so:
struct obj {
int id = 0;
float x = 0;
float y = 0;
int image_w = 0;
int image_h = 0;
int depth = 0;
}
I then have an initialiser function that creates the members of that struct and stores them in an array. If that array is named "instance" then individual members and their values can be accessed by simply doing this: instance[number].x etc..
Then I have a loop or two which handle all these members and do so in the order of their depth value, defined in struct and set in initialiser function. Like so (simplified):
for (i=0;i<maxdepth;i++) {
if (instance[n].depth == i) { doStuff; }
}
In "doStuff" function I check the members' id value in a switch statement and then have them do whatever I want inside case labels; this gives me the option to have some individual behavior within the same struct. And here is where the problem is. Although this works just fine I can't have individual fixed (or starting) variables within certain members without every member having those same variables and obviously with enough members this eventually results in a struct that is simply undesirably big and has a lot of redundancy; wasted resources. E.g I want some members to have speed and direction variables but don't want to give them to static members of the same struct that don't need them.
The question is, how do I achieve this effect without changing the fundamental idea of using structs or is there a better alternative to do this?
And I'm sorry about formatting and all; this is my first question on this website.
My understanding of structs is that the bigger it is the more time it takes to access its individual variables.
Your understanding is fundamentally mistaken. The size of a struct has little (if any) effect on the time required to access an individual variable inside that struct.
Regardless of that, however, your basic idea of structuring the data so one struct contains (or owns a pointer to) some other structs is perfectly fine and reasonable.
What's not so fine or reasonable is making that pointer essentially un-typed so it can refer to any other type. If you want a collection of clothes, you'd probably start with a clothing base class, and then derive various other types from that (coat, shirt, slacks, jeans, etc.). Then the person type might contain (for example) a vector of pointers to clothing, so it can contain pointers to all the other types derived from clothing.
As far as "extending scope" goes...well, I can't say much beyond the fact that I can't make much sense of what you're trying to say there.

Reasonable key types for map used to set properties of related classes?

I'm planning to write a code with classes that have inheritance relationships like the following and have various properties that are associated with material types:
Abstract base class Foo. No properties associated with it.
Foo1GeneralElastic inherits from class Foo and has the properties associated with a possibly anisotropic elastic material.
Foo2GeneralElastic also inherits from class Foo and has the same kinds of material properties as Foo1GeneralElastic, but is otherwise different.
Foo1PiezoElastic inherits from Foo1GeneralElastic and has both piezoelectric properties as well as generic elastic ones.
Foo1IsotropicElastic inherits from Foo1GeneralElastic, but does not share its properties.
I decided that the abstract base class would have one or more methods that take a map of type MyPropMap, defined as:
typedef std::map<PropertyLabel,std::vector<double> > MyPropMap
I have a few different options on what the PropertyLabel type could be, and I'm trying to weigh the pros and cons of each:
Have the PropertyLabel be an enum: This would be lightweight, but it would basically be a bag of labels for all the different properties of every material that I'm considering.
Have the PropertyLabel be just an int: Here, I'd have separate header files for each material type, each of which would contain definition of static integer constants that would be labels for the relevant material properties. For example, MatPropKeyGenElastic.hpp would define the integer constant ELASTICITY_MATRIX, MatPropKeyIsotropicElastic.hpp would define the constants ELASTIC_MODULUS and POISSONS_RATIO, and MatPropKeyPiezoElastic.hpp would #include the file MatPropKeyGenElastic.hpp and additionally define the constant PIEZO_CONST_MATRIX.
The tricky thing would be to make sure that none of the constants that could be used together would have the same values. That could be accomplished by generating the header files with a script that would set the values of these constants to unique values.
Have the PropertyLabel be a std::string From here I could take things a few different ways. I could just have string literals like "ELASTICITY_MATRIX" in the code and rely on these literals never being misspelled---an error that would be caught at run-time rather than compile time. I could define string constants in way analogous to the scheme above for integer constants, and the task of keeping the constants unique would be trivial: just set the value of ELASTICITY_MATRIX to "ELASTICITY_MATRIX", the value of POISSONS_RATIO to "POISSONS_RATIO", etc.
The catch I see with that, aside from the extra overhead, is that I've seen horror stories relating to global static constants of non-PODs, such as those in the comments in the topics non-integral constants and Defining class string constants in C++?. I suppose that I could have the global static constants be const char[] arrays, which are PODs that would be implicitly converted into std::strings when used as map keys (and, no, I am not planning on letting the map key itself be const char*). I could also define the string literals with the preprocessor, but then I couldn't keep them within a namespace.
Would you recommend any of the above approaches? Are there hidden traps in them that I hadn't noticed? Are there still other approaches that you would recommend?
I don't recommend to use strings. It's too expensive for such simple task. I vote for enum.
But if it looks too ugly to you to keep all label constants in a single place, you could elaborate more complex approach - use a composite key like pair of two numbers - (class ID, property ID).
Both could be defined as enums, maybe nested. Moreover, class ID could be generated automatically - e.g. using reinterpret_cast on std::type_info pointer or just using std::type_info pointer or std::type_index if supported. Illustrating idea with code:
// PropertyLabel type, could be used as associative container key
struct PropertyLabel: std::pair<const std::type_info*, int>
{
// Template ctor allows implicit conversion from enums
// (actually not only from enums but from any int-compatible types)
// Uncomment explicit keyword if implicit conversions scares you and use
// explicit conversion syntax - PropertyLabel(smth).
template <typename T> /*explicit*/ PropertyLabel(T label):
std::pair<const std::type_info*, int>(&typeid(T), label)
{
}
};
// First property holder
class PropertyUser1
{
public:
enum Labels
{
eProperty1,
eProperty2,
eProperty3,
};
};
// Second property holder
class PropertyUser2
{
public:
enum Labels
{
eProperty1,// Due to class scope you could use same names for different properties
eProperty2,
eProperty3,
};
};
// Usage. A bit dangerous due to implicit conversions, but intuitive and handy:
MyPropMap properties;
properties[PropertyUser1::eProperty1].push_back(42.0);
properties[PropertyUser2::eProperty1].push_back(42.42);
// Will be with explicit ctor:
// properties[PropertyLabel(PropertyUser1::eProperty1)].push_back(42.0);
// properties[PropertyLabel(PropertyUser2::eProperty1)].push_back(42.42);
Looks like it could be improved with more type safety eliminating possibility of using non-enum types like int, e.g. disabling calls like PropertyLabel(42). But this is just to illustrate idea.
I just realized a relatively simple solution that would give me pretty much what I want without too much fuss. For any particular instance of the MyPropMap type, I'm dealing with the properties of one particular kind of material: isotropic elastic, piezoelectric, anisotropic elastic, and so on. Given this, I can wrap the enums corresponding to each material type in its own namespace and put them in the appropriate header file, so for example,
// MatPropKey/IsotropicElastic.hpp:
namespace IsotropicElastic {
enum { ELASTIC_MODULUS, POISSONS_RATIO };
}
// MatPropKey/GenElastic.hpp
namespace GenElastic {
enum { ELASTICITY_MATRIX }
}
// MatPropKey/PiezoElastic.hpp
namespace PiezoElastic {
enum { PIEZO_CONST_MATRIX, ELASTICITY_MATRIX }
}
There is some redundancy here, but I can live with that. So long as I stick to the above convention, then within each namespace, the enum values are unique, and so long as I only use the enum values within a particular namespace for each instance of MyPropMap---which I want to do anyway---I'm fine. (Realistically, I'd also want to wrap each of these namespaces within a common MPKey namespace.) Of course, this isn't foolproof. A sufficiently creative fool could, for example, decide to #include both GenElastic.hpp and PiezoElastic.hpp and then use GenElastic::ELASTICITY_MATRIX with the PiezoElastic::PIEZO_CONST_MATRIX. Bad things could then happen. Still, the code communicates how the named constants are supposed to be grouped, and avoiding unwanted name clashes is trivial.
Wish I thought of it earlier.
After some thought, I realized a few things:
It's better to wrap the map within a class, so that I have a bit more control over how it is written.
Even the wrapped map is generic and has to be able to accommodate any material parameter type, so there's only so much compile-type safety that I can provide.
Given this, I decided to design a MatProp class roughly as follows:
#include <vector>
#include <map>
class MatProp {
public:
// Skipping the constructor details ...
void setProp_Raw(int propId, double val);
void getProp_Raw(int propId, double & val) const;
void setProp_Raw(int propId, const std::vector<double> & vals);
void getProp_Raw(int propId, std::vector<double> & vals) const;
// More overloaded set/get funcs for complex scalars and vectors ...
private:
// The typedef allows me to write MatPropMap_::iterator, etc. in the
// implementation of the member functions, which is handy if, say,
// I want to swap the std::map for an unordered_map later on.
typedef std::map<PropertyLabel,std::vector<double> > MatPropMap_;
MatPropMap_ matPropMap_;
};
The set/get functions are suffixed with _Raw because it's easy to put in a wrong combination of property ID and value. I could pass in information to the constructor of MatProp so that the inputs to these functions could be validated at run time, but setting that up could get clunky and make the class harder to use. To add some extra safety, I can do this, for example:
void setIsotropicLinearElasticParameter(MatProps mProp,
ElasPropEnum propId, // ELASTIC_MODULUS and POISSONS_RATIO are the
// *only* valid values of this parameter.
double val) {
mProp.setParam_Raw(propId, val);
}
The function is simple, but I'm declaring clearly that (1) only two keys are allowed and (2) they really are supposed to be of type double. The interface isn't totally foolproof, but it's fairly easy to use correctly and takes some effort to use wrong. FWIW, a similar thing was done here: http://blog.knatten.org/2010/04/23/make-apis-hard-to-use-incorrectly/.

c++ container with with variable size and variable types

I am trying to create something like a list. However, different instances of the list may have a different number of entries, and the type of entry is based on input given by the user. For example, the user states that they want the structure of each entry in the list to contain an int id, a std::string name, a double metricA, and a long metricB. Based on this input, the following is created:
struct some_struct {
int id;
std::string name;
double metricA;
long metricB;
}
list<some_struct> some_list;
The user input may be read from a file, input on the screen, etc. Additionally, their are a variable number of entries in some_struct. In other words, it may have the entries listed above, it may have just 2 of them, or it may have 10 completely different ones. Is there someway to create a struct like this?
Additionally, being able to apply comparison operators to each member of some_struct is a must. I could use boost::any to store the data, but that creates issues with comparison operators, and also incurs more overhead than is ideal.
C++ is a strongly-typed language, meaning you have to declare your data structure types. To that end you cannot declare a struct with arbitrary number or type of members, they have to be known upfront.
Now there are ways, of course, to deal with such issues in C++. To name a few:
Use a map (either std::map or std::unordered_map) to create a "table" instead of a structure. Map strings to strings, i.e. names to string representation of the values, and interpret them to your heart.
Use pre-canned variant type like boost::any.
Use polymorphism - store pointers to base in the list, and have the virtual mechanism dispatch operations invoked on the values.
Create a type system for your input language. Then have table of values per type, and point into appropriate table from the list.
There probably as many other ways to do this as there are C++ programmers.
There are many ways to solve the problem of data structures with varying members and which is best depends a lot on how exactly it is going to be used.
The most obvious is to use inheritance. You derive all your possibilities from a base class:
struct base_struct {
int id;
std::string name;
};
list<base_struct*> some_list;
struct some_struct : public base_struct {
double metricA;
};
struct some_other_struct : public base_struct {
int metricB;
};
base_struct *s1 = new some_struct;
s1->id = 1;
// etc
base_struct *s2 = new some__other_struct;
s2->id = 2;
// etc
some_list.push_back(s1);
some_list.push_back(s2);
The tricky bit is that you'll have to make sure that when you get elements back out, you case appropriately. dynamic_cast can do this in a type-safe manner:
some_struct* ss = dynamic_cast<some_struct*>(some_list.front());
You can query the name before casting using type_info:
typeid(*some_list.front()).name();
Note that both these require building with RTTI, which is usually OK, but not always as RTTI has a performance cost and can bloat your memory footprint, especially if templates are used extensively.
In a previous project, we dealt with something similar using boost any. The advantage of any is that it allows you to mix types that aren't derived from one another. In retrospect, I'm not sure I'd do that again because it made the code a bit too apt to fail at runtime because type checking is being deferred until then. (This is true of the dynamic_cast approach as well.
In the bad old C days, we solved this same problem with a union:
struct base_struct {
int id;
std::string name;
union { // metricA and metricB share memory and only one is ever valid
double metricA;
int metricB;
};
};
Again, you have the problem that you have to deal with ensuring that it is the right type yourself.
In the era before the STL, many container systems were written to take a void*, again requiring the user to know when to cast. In theory, you could still do that by saying list<void*> but you'd have no way to query the type.
Edit: Never, ever use the void* method!
I ended up using a list with a boost::variant. The performance was far better than using boost::any. It went something like this:
#include <boost/variant/variant.hpp>
#include <list>
typedef boost::variant< short, int, long, long long, double, string > flex;
typedef pair<string, flex> flex_pair;
typedef list< flex_pair > row_entry;
list< row_entry > all_records;

Determining whether a non-object variable is initialized in C++

So, let's say, in a class in C++, I have a variety of member variables. Structs, strings, ints, etc. etc. Could be anything. These variables can or cannot be set by the initialization of the object of this class. Given int a, float b, char c, sometimes all of them or none of them can be set. When they are set, they can be set to any possible value of the variable. I would like to find someway of setting, and determining whether or not a variable has been set without:
1) Lots of casting. I could always create a Data_Value decorator class that has a boolean, and template it to whatever the given variable is. This would require calling a_data_value.value and a_data_value.isInitialized.
2) Lots of extra Boolean variables. I'd rather not have bool a_initialized, bool b_initialized.
What I would really like to do is something like this:
Python add to a function dynamically
in C++, with any and all variables, including primitives. Tall order I know, and I'm fully expecting the pessimistic answer.
You're right. It's impossible to determine at runtime whether a primitive is "set". Some compilers will warn you for some cases of using uninitialized values, but this is not at all guaranteed.
I would use a nullable template. See http://www.codeproject.com/KB/mcpp/CNullable.aspx
Suppose you have
class Bob {
int a;
int b;
double c;
complex<double> d;
Bob () : a(), b(), c(), d() {}
};
When you create a new Bob, everything will be set to default (zero in this case).
There is no set or not set state for primitive types. They always hold some value.
If you want to rewrite Python in C++ you can.
You'd need an efficient unordered_map class keyed by string. The string would be the variable name.
Each variable value would be a class (call it a VARIANT, heh) that can hold any primitive value.
Then instead of a C++ struct you'd make your "struct" be an instance of your unordered_map aka dictionary.
If the variable name is found in the dictionary then it was set and you can return the value. If it isn't found it was never set.
If you plan to reference your dictionary keys by name from within C++ you will want to use the following for efficiency:
Instead of:
VARIANT v = dict["name"];
Use:
static const std::string name_key("name");
VARIANT v = dict[name_key];
That way instead of building a std::string containing "name" for the key lookup every time into the function, it will be done once.

C++ Class or Struct compatiblity with C struct

Is it possible to write a C++ class or struct that is fully compatible with C struct. From compatibility I mean size of the object and memory locations of the variables. I know that its evil to use *(point*)&pnt or even (float*)&pnt (on a different case where variables are floats) but consider that its really required for the performance sake. Its not logical to use regular type casting operator million times per second.
Take this example
Class Point {
long x,y;
Point(long x, long y) {
this->x=x;
this->y=y;
}
float Distance(Point &point) {
return ....;
}
};
C version is a POD struct
struct point {
long x,y;
};
The cleanest was to do this is to inherit from the C struct:
struct point
{
long x, y;
};
class Point : public struct point
{
public:
Point(long x, long y)
{ this->x=x; this->y=y; }
float Distance(Point &point)
{ return ....; }
}
The C++ compiler guarantees the C style struct point has the same layout as with the C compiler. The C++ class Point inherits this layout for its base class portion (and since it adds no data or virtual members, it will have the same layout). A pointer to class Point will be converted to a pointer to struct point without a cast, since conversion to a base class pointer is always supported. So, you can use class Point objects and freely pass pointers to them to C functions expecting a pointer to struct point.
Of course, if there is already a C header file defining struct point, then you can just include this instead of repeating the definition.
Yes.
Use the same types in the same order in both languages
Make sure the class doesn't have anything virtual in it (so you don't get a vtable pointer stuck on the front)
Depending on the compilers used you may need to adjust the structure packing (usually with pragmas) to ensure compatibility.
(edit)
Also, you must take care to check the sizeof() the types with your compilers. For example, I've encountered a compiler that stored shorts as 32 bit values (when most will use 16). A more common case is that an int will usually be 32 bits on a 32-bit architecture and 64 bits on a 64-bit architecture.
POD applies to C++. You can have member functions. "A POD type in C++ is an aggregate class that contains only POD types as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type"
You should design your POD data structures so they have natural alignment, and then they can be passed between programs created by different compilers on different architectures. Natural alignment is where the memory offset of any member is divisible by the size of that member. IE: a float is located at an address that is divisible by 4, a double is on an address divisible by 8. If you declare a char followed by a float, most architectures will pad 3 bytes, but some could conceivably pad 1 byte. If you declare a float followed by a char, all compilers (I ought to add a source for this claim, sorry) will not pad at all.
C and C++ are different languages but it has always been the C++'s intention that you can have an implementation that supports both languages in a binary compatible fashion. Because they are different languages it is always a compiler implementation detail whether this is actually supported. Typically vendors who supply both a C and C++ compiler (or a single compiler with two modes) do support full compatibility for passing POD-structs (and pointers to POD-structs) between C++ code and C code.
Often, merely having a user-defined constructor breaks the guarantee although sometimes you can pass a pointer to such an object to a C function expecting a pointer to a struct with and identical data structure and it will work.
In short: check your compiler documentation.
Use the same "struct" in both C and C++. If you want to add methods in the C++ implementation, you can inherit the struct and the size should be the same as long as you don't add data members or virtual functions.
Be aware that if you have an empty struct or data members that are empty structs, they are different sizes in C and C++. In C, sizeof(empty-struct) == 0 although in C99, empty-structs are not supposed to be allowed (but may be supported anyway as a "compiler extension"). In C++, sizeof(empty-struct) != 0 (typical value is 1).
In addition to other answers, I would be sure not to put any access specifiers (public:, private: etc) into your C++ class / struct. IIRC the compiler is allowed to reorder blocks of member variables according to visibility, so that private: int a; pubic: int b; might get a and b swapped round. See eg this link: http://www.embedded.com/design/218600150?printable=true
I admit to being baffled as to why the definition of POD does not include a prohibition to this effect.
As long as your class doesn't exhibit some advanced traits of its kind, like growing something virtual, it should be pretty much the same struct.
Besides, you can change Class (which is invalid due to capitalization, anyway) to struct without doing any harm. Except for the members will turn public (they are private now).
But now that I think of your talking about type conversion… There's no way you can turn float into long representing the same value or vice versa by casting pointer type. I hope you only want it these pointers for the sake of moving stuff around.