When to Use A Struct Over a Class

Hi all,

I wanted to share a bit of a personal eureka moment I had yesterday, I'm still trying to get to grips with the language and I've been making progress in understanding nuanced concepts like invariance, something clicked for me yesterday when I was doing a practice exercise which I'm super excited to share, it might be a bit embarrassing..... I feel like a kid learning to ride a bike.

This isn't a question per se or me asking for help..... its more of a Look Ma No Hands moment for me.

I've been trying to understand the difference between a struct and a class in C++ since before the holidays. I know that the core difference is a Structs access specifier defaults to public and a class defaults to private, but the rabbit hole I went down was when to use a struct over a class.

I worked through an example I found on Planet-Source-Code the example was a program that asks the user for five positive integers and adds them together. The original code used a class with public data members, but it dawned on me that this could be better implemented as a struct, which is just a bundle of data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  #include <iostream>

  using namespace std; 

 
struct Adder
{

    // Data Members
    int num1;
    int num2;
    int num3;
    int num4;
    int num5; 

    // Member Functions
    // Usually I would separate the interface from the implementation but 
    // this is too small of an example to warrant that.

    int addTogether(int num1, int num2, int num3,
                    int num4, int num5)
    {
        return(num1 + num2 + num3 + num4 + num5);                                                                 
    }                                                                                               
};                                                                                                  


What I realised in the general sense of my understanding of the concept was that there is no real invariance with the data members, all the values (numbers) are subject to change because they are going to be added together,
and the data members in this context don't need to be private, these are the two main considerations I feel are what determines in general if you choose a struct over a class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{

  

    // Instance Variable(s)
    Adder values; 

    cout << "\n\t Welcome to 5 Number Adder ";
    cout << "\n\n";
    cout << "Please Enter 5 positive integers: "; 
    cin >> values.num1 >> values.num2 >> values.num3 >> values.num4                                 
        >> values.num5;
    cout << endl;
    cout << "The total sum  = " << values.addTogether(values.num1, 
                                                      values.num2, 
                                                      values.num3,
                                                      values.num4, 
                                                      values.num5) << ".";
    cout << endl; 

    return 0;
}


I just want to ask if this makes sense and if I'm on the right track conceptually with how I've understood invariance and how I've formulated my two considerations for using a struct or a class? I am eager to learn and understand more.

Thanks
> I just want to ask if this makes sense and if I'm on the right track conceptually with how I've understood
> invariance and how I've formulated my two considerations for using a struct or a class?

Invariants.

You are on the right track.
CoreGuidelines:

Use class if the class has an invariant; use struct if the data members can vary independently
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-struct

Use class rather than struct if any member is non-public
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-class


This is what most style guides would advocate. I don't adhere to these two rules in my own private code;
I use struct if the member declared first has public access, class otherwise.
Thanks a million @JLBorges your answer has given me an extra positive boost for the day! :)
On top of this, at your job you will likely be told how to decide which to use. My last c++ job was similar result but defined very simply (I believe our standards rules were cut down to < 2 pages) ... structs had no methods (no ctor, no operators, no methods at all). If it had a method, it was to be class.

your member function doesn't use your member variables
you may do
1
2
3
4
5
6
7
values.addTogether(
   values.num1,
   values.num1,
   42,
   another.num4,
   another.num5
);
¿so what's the point?

1
2
3
4
5
6
7
8
int Adder::addTogether() const{
   return
      this->num1
      + this->num2
      + this->num3
      + this->num4
      + this->num5;
}
To show why ne555's change is important, consider this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main()
{
    // Instance Variable(s)
    Adder values; 

    cout << "\n\t Welcome to 5 Number Adder ";
    cout << "\n\n";
    cout << "Please Enter 5 positive integers: "; 
    cin >> values.num1 >> values.num2 >> values.num3 >> values.num4                                 
        >> values.num5;
    cout << endl;
    cout << "The total sum  = " << values.addTogether(1,2,3,4,5);   // WTF??
    cout << endl; 

    return 0;
}

Your original addTogether() method only ever makes sense if it's called with a very specific set of parameters. Where's the use in that?
Thanks, @ne55 & dhayden

I see where I messed up now, I assumed the arguments of the Structs member function were the same as the data members.

1
2
3
4
5
int addTogether(int num1, int num2, int num3, // These arguments are not the data members
                        int num4, int num5)          // they are their own variables local in scope to the 
    {                                                         // "member" function. 
        return(num1 + num2 + num3 + num4 + num5);                                                                 
    }         


So all I essentially did was declare a member function that takes in any 5 arguments of type int and named them the same things as the data members..... I think??? **slaps forehead**.

Thanks again for the nudge.

I took this code from an exercise I found online.

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=13768&lngWId=3
Last edited on
I'd suggest you find a different source for your inspiration, that code is totally horrible. There is really no sense of having that class since that function never uses any of the class member functions. Also anytime you start adding numbers to variable names it is usually time to be thinking about vectors.

I took this code from an exercise I found online.
Just because someone posts online doesn't mean they have any talent at all. If you have an account at that site, I urge you to rate the code "poor"
Topic archived. No new replies allowed.