7

I am not very familiar with C++ , and while I am trying some test programms I came to a question regarding the best if I may say so way to define some primitive elements in C++ code.

Let's take a class that describes rectangles. It would create them, draw them , rotate, resize, etc... now in most cases we have to deal with points on the canvas. The rectangle its self is described by 2 points: Upper Left and Lower Right corner. Also in order to Rotate it, you need an angle, and a point(anchor point). Or maybe to move it you need a new anchor point for the given rectangle. I guess I made my point in using points . So what is more efficient ? to define this primitive point as a class or as a struct?

class cPoint
{
public: 
 int X;
 int Y;
};

or

typedef struct
{
 int X;
 int Y;
}sPoint;
Sagi2313
  • 105
  • 1
  • 1
  • 10
  • 4
    `struct sPoint { ... };`, you don't need the typedef in C++. The struct version involves less typing, so it's "more efficient". – Mat Jan 24 '14 at 17:05
  • This might also help: http://stackoverflow.com/questions/92859/what-are-the-differences-between-struct-and-class-in-c – Nico Jan 24 '14 at 17:06

8 Answers8

22

Niether are more efficient. On a technical level, there is no difference between a class and a struct aside from default visibility of members (public in struct, private in class) and default inheritance model (public in struct, private in class).

They typedef struct {} name model is not idiomatic in C++. In fact, it's an abomination -- a holdover from C. Don't use this model. Use this struct name {}; instead. Using the typedef struct {} name; model doesn't gain you anything in C++ (it was needed in C), and may cost you sojmething in terms of maintainability. For instance, it might be harder to grep for typedef struct declarations. But since it doesn't gain you anything by doing this, there's no compelling reason not to simply do struct name {}; in C++.

Aside from technical issues, the differences between struct and class are semantic ones. It is traditional and expected that objects declared as structs are simple objects which consist of only public: data members (so-called PODs). If it has private or protected data, is expected to be derived from, or has any methods, it is declared as a class.

This guideline is open to interpretation, and is just that -- a guideline. There is nothing to prevent you from declaring an abstract base class as a struct, for example. However you may want to consider following this guideline in order to follow the Principle of Least Surprise, making your code easier to understand and maintain.

Community
  • 1
  • 1
John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • `typedef`s do still have use in C++ if you want semantic information about what sort of values variables used in specific contexts hold or (more commonly in my experience, aside from those inherited from C like `size_t`) to simplify implementation of templated classes/structs (for example, including `typedef related_templated_type related_type;};` in `template class A {...};` would allow you to refer to the related type within the body of the class without having to supply the template parameter each time; this is also how many STL classes define inner types, iirc). – JAB Jan 24 '14 at 17:56
  • `typedef struct` is not *needed* in C. I never use it. I prefer `struct X {};` and `struct X var;` – fredoverflow Jan 24 '14 at 18:35
  • @JAB: `typedef`s in general have plenty of use in C++, but I'm talking specifically about `typedef`ing an anonymous `struct` – John Dibling Jan 24 '14 at 18:38
  • @JohnDibling The way I phrased my comment was bad, it was meant more as a general note that `typedef` does still have use in C++ even if not in this specific case rather than something directed at you specifically. – JAB Jan 24 '14 at 19:56
4

Both are nearly equivalent. More precisely, struct { is the same as class {public:

An optimizing compiler would probably generate exactly the same code. Use MELT or simply pass -fdump-tree-all (beware, that option produces hundreds of dump files) to g++ (assuming you use a recent GCC compiler) -preferably with some optimization like -O - to find out (or look at the produced assembler code with g++ -O -fverbose-asm -S ...)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

typedef struct is actually the C way to do this. In C++ the two versions would look very similar: Your class as written, and the struct as follows:

struct sPoint
{
 int X;
 int Y;
};

The two forms are functionally identical but you can provide your future maintainers with significant information by picking and sticking to some convention about how they're used. For example one approach is that if you intend to make the data elements private and give it useful methods (for example if you use inline accessors you can insert print calls every time the methods are used) then by all means make it a class. If you intend to have the data be public and access them as members then make it a struct.

Mark B
  • 95,107
  • 10
  • 109
  • 188
3

There's no performance difference between a class and a struct

A class defaults to private access, whilst a struct defaults to public access. If interoperability with C is an issue for you then you'll have to use struct, and obviously it can't have any member functions.

As an aside, there's no std::is_struct in the standard library. Instead the std::is_class method returns true if the type is a class or a structure.

Sean
  • 60,939
  • 11
  • 97
  • 136
  • In c++ you can have member functions in a struct. You're thinking about C. – Salgar Jan 24 '14 at 17:11
  • 2
    @Salgar - yes, what I'm saying is that if you're writing structs that need to be used in C and C++ then you need to make sure you don't add member functions to the struct. – Sean Jan 24 '14 at 17:13
1

Simply put, the first way is more C++, and the second way is more C. Both work, while the first way is more 'standard' now.

AndyG
  • 39,700
  • 8
  • 109
  • 143
  • This is wrong, using a struct is no more or less "C++" - You can do object oriented programming with either, there is no difference apart from default visibility rules. – Salgar Jan 24 '14 at 17:13
  • @Salgar `typedef struct` is absolutely more of a C notion. See the other answers. Consult Google, even. – AndyG Jan 24 '14 at 17:14
  • @Salgar It is not really "wrong". The `typedef struct ...` pattern is required in C, but not in C++. Though, neither makes OOP any more, nor less, difficult. – Zac Howland Jan 24 '14 at 17:15
  • So I've removed the part about OOP. – AndyG Jan 24 '14 at 17:16
1

A struct in C++ is like a class that would have public members by default*

There is no other formal difference, though your code would probably look confusing if you started using structs as classes, especially the inheritance mechanisms where data privacy is a major benefit.

If you are about to declare private/protected members, there is really little point in using a struct, though your code will still be 100% legal.


*including inherited members, since the zealots and nitpickers around seem to think the point is of a capital importance and only ignorant heatens would fail to mention it.
Except for the fact that this fine doctrine point is defined (or rather hinted, since the inference that base classes are simply defining inherited members is left to the sagacity of the reader) in another verse of the Stoustrup Holy Bible, there is really nothing to fuss about IMHO.

kuroi neko
  • 8,479
  • 1
  • 19
  • 43
  • 1
    Wrong. A `struct` can have all the access specifiers a class has, and inheritance. – juanchopanza Jan 24 '14 at 17:09
  • @juanchoanza Well okay, I oversimplified it. I don't see why you would want to derive a struct, but you're right. Answer updated – kuroi neko Jan 24 '14 at 17:11
  • 1
    You would derive a struct for the same reasons you would derive a class. They are basically the same thing. Any difference in usage is *purely* down to convention. – juanchopanza Jan 24 '14 at 17:12
  • Almost there: there is another difference: inheritance is private by default in `class` and publuc by default in `struct`. – juanchopanza Jan 24 '14 at 17:17
  • @juanchopanza Agreed, but as I say in my modified answer, there would be no real benefit of using structs as classes, except saving one line to declare public members. On the other hand, that would make the code slightly more confusing. I am well aware C++ is a dream playground for amateurs of cryptic template code, but I still think sticking to a few widely accepted conventions will not do any harm. – kuroi neko Jan 24 '14 at 17:20
  • 1
    But you said, "There is no other difference," which makes this answer still incorrect -- there is another difference. – John Dibling Jan 24 '14 at 17:20
  • The problem is that these is not one widely accepted convention, but many slightly different ones. And many people's conventions are only there because of a lack of understanding of the meaning differences between `struct` and `class`. Better to know the differences well, that way you don't get surprised by slight differences in use between different conventions. – juanchopanza Jan 24 '14 at 17:24
  • @JohnDibling Ah yes, the famous "public inheritance by default". Frankly, I never saw a case when this mattered a bit, but okay, for the sake of completeness I added it. – kuroi neko Jan 24 '14 at 17:32
  • 1
    This is one of the major reasons why I hate C++'s guts: the number of nitpickers and zealots this language attracts. C++ is inherently obfuscated, and templates are probably the best code obfuscation tool invented after m4 and the Perl regular expressions. There are so many pitfalls in this language that arguing about default access qualifiers for struct inheritance is about as relevant as lecturing a new recruit about the dangers of spraining a finger while pulling the pin of a grenade. – kuroi neko Jan 24 '14 at 17:50
  • It is really quite simple. I don't see what the problem is. class: private members and base classes by defsult. struct, same but public. It is not a hard rule to remember. You just seem to be annoyed that someone pointed out these rules to you. The end. – juanchopanza Jan 24 '14 at 23:46
  • Read my post instead of quoting your catechism or trying to reverse-psychologize me. "public members and base classes by default" is exactly equivalent to "public members and inherited members by default", and since there are no other kinds of members, all this can be shortened to "all members public by default". – kuroi neko Jan 25 '14 at 00:18
  • No, public inheritance does **not** mean all inherited members are public. They keep the access control of the base. – juanchopanza Jan 25 '14 at 08:36
  • You're absolutely right. It does not mean all inherited members are public, and I did not say that. It means all inherited members are public ***by default***, just as I said. i.e. they are public unless some other more restrictive, explicit rule applies. Since public is the less restrictive attribute, any other access specifier will dominate. This is still what public ***by default*** means, as far as I can tell. – kuroi neko Jan 25 '14 at 11:29
  • No, inherited members are nothing by default. They are whatever they were in the thing you are inheriting from. Which could be a class, whose members are private by default. You answer is spreading misinformation. – juanchopanza Jan 25 '14 at 16:19
  • @juanchopanza you're wrong ***and*** stubborn. Inherited members are subject to 2 qualifications, applied in this order: (1) qualifier inside the base class (2) qualifier applied for inheritance (and so on if the inheritance chain grows). Each has a default value (private for classes and public for structs). In the case of structs, this rule amonts to what you say, since public is the weakest qualifier. The only case when default qualifiers will make any difference is a member of a struct with no explicit qualifier inherited by a struct. So more the reasons not to fuss about this moot point. – kuroi neko Jan 25 '14 at 16:37
  • You are saying in your answer that inherited members are public by default. That is patently wrong. The rule is that you get public inheritance by default. Whether the members you inherit are public or not depends on the thing you inherit from. – juanchopanza Jan 25 '14 at 16:40
  • @juanchopanza Yeah, whatever... Call your brethren and downvote me to hell for all I care. – kuroi neko Jan 25 '14 at 16:41
1

To properly declare the struct in your example, use

struct sPoint {
    int X;
    int Y;
};

In general, structs and classes in C++ are identical, except that data is public in a struct by default. The other difference is that the struct keyword cannot be used as the type in a template, although a struct can be used as the parameter.

There is a more thorough discussion here: C++ - struct vs. class

Community
  • 1
  • 1
weitzner
  • 440
  • 3
  • 12
1

technically, struct{} and class{} are the same.

they differ on semantic level, with different member visibility.

struct{...} is equivalent to class{public:...}

And, it is also legal to declare a class using struct keyword. (add member functions, access specifier to struct{})

Generally, using struct for Plain-Old-Data (POD) type, class for Object-Oriented type to improve readability.

typedef struct{} should only be used to hide implementation detail(eg: supply a close-source library to users)

From my opinion, in your case, using struct is better, because Point's member need to be modified directly by other code.

wacky6
  • 135
  • 3
  • Thank you for suggesting a solution to my *Point* question. But if I wanted to hide X,Y from **main** and only provide a Point object that is either used as public from other classes (so other classes **see** X,Y), or let **main** use only member functions to alter a point. For example a point would be part of a bigger object:Rectangle. So Rectangle cal change it's own Points Internally, but the main code can't change the X of the rectangles upper left corner. Then , what should point be? – Sagi2313 Jan 31 '14 at 12:51
  • You can use `friend` keyword to declare a friend class. Example: [link](http://www.cplusplus.com/doc/tutorial/inheritance/) – wacky6 Feb 01 '14 at 14:32