While C++ provides a number of fundamental data types (e.g. char, int, long, float, double, etc…) that are often sufficient for solving relatively simple problems, it can be difficult to solve complex problems using just these types. One of C++’s more useful features is the ability to define your own data types that better correspond to the problem being solved. You have already seen how enumerated types and structs can be used to create your own custom data types.
Here is an example of a struct used to hold a date:
1 2 3 4 5 6 |
struct DateStruct { int year{}; int month{}; int day{}; }; |
Enumerated types and data-only structs (structs that only contain variables) represent the traditional non-object-oriented programming world, as they can only hold data. In C++11, we can create and initialize this struct as follows:
1 |
DateStruct today { 2020, 10, 14 }; // use uniform initialization |
Now, if we want to print the date to the screen (something we probably want to do a lot), it makes sense to write a function to do this. Here’s a full program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> struct DateStruct { int year{}; int month{}; int day{}; }; void print(const DateStruct &date) { std::cout << date.year << '/' << date.month << '/' << date.day; } int main() { DateStruct today { 2020, 10, 14 }; // use uniform initialization today.day = 16; // use member selection operator to select a member of the struct print(today); return 0; } |
This program prints:
2020/10/16
Classes
In the world of object-oriented programming, we often want our types to not only hold data, but provide functions that work with the data as well. In C++, this is typically done via the class keyword. The class keyword defines a new user-defined type called a class.
In C++, classes and structs are essentially the same. In fact, the following struct and class are effectively identical:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
struct DateStruct { int year{}; int month{}; int day{}; }; class DateClass { public: int m_year{}; int m_month{}; int m_day{}; }; |
Note that the only significant difference is the public: keyword in the class. We will discuss the function of this keyword in the next lesson.
Just like a struct declaration, a class declaration does not allocate any memory. It only defines what the class looks like.
Warning
Just like with structs, one of the easiest mistakes to make in C++ is to forget the semicolon at the end of a class declaration. This will cause a compiler error on the next line of code. Modern compilers like Visual Studio 2010 will give you an indication that you may have forgotten a semicolon, but older or less sophisticated compilers may not, which can make the actual error hard to find.
Class (and struct) definitions are like a blueprint -- they describe what the resulting object will look like, but they do not actually create the object. To actually create an object of the class, a variable of that class type must be defined:
1 |
DateClass today { 2020, 10, 14 }; // declare a variable of class DateClass |
Member Functions
In addition to holding data, classes (and structs) can also contain functions! Functions defined inside of a class are called member functions (or sometimes methods). Member functions can be defined inside or outside of the class definition. We’ll define them inside the class for now (for simplicity), and show how to define them outside the class later.
Here is our Date class with a member function to print the date:
1 2 3 4 5 6 7 8 9 10 11 12 |
class DateClass { public: int m_year{}; int m_month{}; int m_day{}; void print() // defines a member function named print() { std::cout << m_year << '/' << m_month << '/' << m_day; } }; |
Just like members of a struct, members (variables and functions) of a class are accessed using the member selector operator (.):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> class DateClass { public: int m_year{}; int m_month{}; int m_day{}; void print() { std::cout << m_year << '/' << m_month << '/' << m_day; } }; int main() { DateClass today { 2020, 10, 14 }; today.m_day = 16; // use member selection operator to select a member variable of the class today.print(); // use member selection operator to call a member function of the class return 0; } |
This prints:
2020/10/16
Note how similar this program is to the struct version we wrote above.
However, there are a few differences. In the DateStruct version of print() from the example above, we needed to pass the struct itself to the print() function as the first parameter. Otherwise, print() wouldn’t know what DateStruct we wanted to use. We then had to reference this parameter inside the function explicitly.
Member functions work slightly differently: All member function calls must be associated with an object of the class. When we call “today.print()”, we’re telling the compiler to call the print() member function, associated with the today object.
Now let’s take a look at the definition of the print member function again:
1 2 3 4 |
void print() // defines a member function named print() { std::cout << m_year << '/' << m_month << '/' << m_day; } |
What do m_year, m_month, and m_day actually refer to? They refer to the associated object (as determined by the caller).
So when we call “today.print()”, the compiler interprets m_day
as today.m_day
, m_month
as today.m_month
, and m_year
as today.m_year
. If we called “tomorrow.print()”, m_day
would refer to tomorrow.m_day
instead.
In this way, the associated object is essentially implicitly passed to the member function. For this reason, it is often called the implicit object.
We’ll talk more about how the implicit object passing works in detail in a later lesson in this chapter.
The key point is that with non-member functions, we have to pass data to the function to work with. With member functions, we can assume we always have an implicit object of the class to work with!
Using the “m_” prefix for member variables helps distinguish member variables from function parameters or local variables inside member functions. This is useful for several reasons. First, when we see an assignment to a variable with the “m_” prefix, we know that we are changing the state of the class instance. Second, unlike function parameters or local variables, which are declared within the function, member variables are declared in the class definition. Consequently, if we want to know how a variable with the “m_” prefix is declared, we know that we should look in the class definition instead of within the function.
By convention, class names should begin with an upper-case letter.
Rule
Name your classes starting with a capital letter.
Here’s another example of 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 24 25 26 27 28 29 30 31 |
#include <iostream> #include <string> class Employee { public: std::string m_name{}; int m_id{}; double m_wage{}; // Print employee information to the screen void print() { std::cout << "Name: " << m_name << " Id: " << m_id << " Wage: $" << m_wage << '\n'; } }; int main() { // Declare two employees Employee alex { "Alex", 1, 25.00 }; Employee joe { "Joe", 2, 22.25 }; // Print out the employee information alex.print(); joe.print(); return 0; } |
This produces the output:
Name: Alex Id: 1 Wage: $25 Name: Joe Id: 2 Wage: $22.25
With normal non-member functions, a function can’t call a function that’s defined “below” it (without a forward declaration):
1 2 3 4 5 6 7 8 |
void x() { // You can't call y() from here unless the compiler has already seen a forward declaration for y() } void y() { } |
With member functions, this limitation doesn’t apply:
1 2 3 4 5 6 |
class foo { public: void x() { y(); } // okay to call y() here, even though y() isn't defined until later in this class void y() { }; }; |
Member types
In addition to member variables and member functions, class
es can have member types or nested types (including type aliases). In the following example, we’re creating a calculator where we can swiftly change the type of number it’s using if we ever need to.
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 26 27 28 29 30 31 32 33 34 |
#include <iostream> #include <vector> class Calculator { public: using number_t = int; // this is a nested type alias std::vector<number_t> m_resultHistory{}; number_t add(number_t a, number_t b) { auto result{ a + b }; m_resultHistory.push_back(result); return result; } }; int main() { Calculator calculator{}; std::cout << calculator.add(3, 4) << '\n'; // 7 std::cout << calculator.add(99, 24) << '\n'; // 123 for (Calculator::number_t result : calculator.m_resultHistory) { std::cout << result << '\n'; } return 0; } |
Output
7 123 7 123
In such a context, the class name effectively acts like a namespace for the nested type. From inside the class, we only need reference number_t
. From outside the class, we can access the type via Calculator::number_t
.
When we decide that an int
no longer fulfills our needs and we want to use a double
, we only need to update the type alias, rather than having to replace every occurrence of int
with double
.
Type alias members make code easier to maintain and can reduce typing. Template classes, which we’ll cover later, often make use of type alias members. You’ve already seen this as std::vector::size_type
, where size_type
is an alias for an unsigned integer.
Nested types cannot be forward declared. Generally, nested types should only be used when the nested type is used exclusively within that class. Note that since classes are types, it’s possible to nest classes inside other classes -- this is uncommon and is typically only done by advanced programmers.
A note about structs in C++
In C, structs can only hold data, and do not have associated member functions. In C++, after designing classes (using the class keyword), Bjarne Stroustrup spent some amount of time considering whether structs (which were inherited from C) should be granted the ability to have member functions. Upon consideration, he determined that they should, in part to have a unified ruleset for both. So although we wrote the above programs using the class keyword, we could have used the struct keyword instead.
Many developers (including myself) feel this was the incorrect decision to be made, as it can lead to dangerous assumptions. For example, it’s fair to assume a class will clean up after itself (e.g. a class that allocates memory will deallocate it before being destroyed), but it’s not safe to assume a struct will. Consequently, we recommend using the struct keyword for data-only structures, and the class keyword for defining objects that require both data and functions to be bundled together.
Rule
Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions.
You have already been using classes without knowing it
It turns out that the C++ standard library is full of classes that have been created for your benefit. std::string, std::vector, and std::array are all class types! So when you create an object of any of these types, you’re instantiating a class object. And when you call a function using these objects, you’re calling a member function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <string> #include <array> #include <vector> #include <iostream> int main() { std::string s { "Hello, world!" }; // instantiate a string class object std::array<int, 3> a { 1, 2, 3 }; // instantiate an array class object std::vector<double> v { 1.1, 2.2, 3.3 }; // instantiate a vector class object std::cout << "length: " << s.length() << '\n'; // call a member function return 0; } |
Conclusion
The class keyword lets us create a custom type in C++ that can contain both member variables and member functions. Classes form the basis for Object-oriented programming, and we’ll spend the rest of this chapter and many of the future chapters exploring all they have to offer!
Quiz time
Question #1
a) Create a class called IntPair that holds two integers. This class should have two member variables to hold the integers. You should also create two member functions: one named “set” that will let you assign values to the integers, and one named “print” that will print the values of the variables.
The following main function should execute:
1 2 3 4 5 6 7 8 9 10 11 12 |
int main() { IntPair p1; p1.set(1, 1); // set p1 values to (1, 1) IntPair p2{ 2, 2 }; // initialize p2 values to (2, 2) p1.print(); p2.print(); return 0; } |
and produce the output:
Pair(1, 1) Pair(2, 2)
(h/t to reader Pashka2107 for this quiz idea)
b) Why should we use a class for IntPair instead of a struct?
![]() |
![]() |
![]() |
Hi Alex,
@ "A note about structs in C++" -> "Many developers (including myself) feel this was the incorrect decision to be made..":
1. I assume using structs for data-only and classes for data + x is de facto standard in C++, right?
2. What are the main arguments of developers using structs in C++ instead of classes (if there are any)?
Thanks! :)
1) Yes. For example, the Google C++ style guide explicitly states, "Use a struct only for passive objects that carry data; everything else is a class."
2) Structs are still useful for moving data around (e.g. passing or returning structured data to/from a function) when no behaviors are required. But that happens a lot less in C++ than it did in C since often we do want to bundle data and behaviors together.
Hmmm, it actually seems easier to use class than struct. From the main() included it would indicate two members - set() and print() so the solution appears thus:
Hi Nigel!
* Line 10, 11 or 27: Initialize your variables with uniform initialization.
* Line 15, 16: Those are initializer lists, not what you want. You're only assigning, a "=" suffices.
I've been learning programming for over a year and a half and this is the first time I read a clear explanation of OO and the differences coming from a traditional programming background, like C.
So THANK YOU for being one of the only good teacher out there!
Hello again!
I could not solve quizz 1a :(....
What is "set"?
"You should also create two member functions: one named “set” that will let you assign values to the integers"
It kind of seems such a serpentine way... so first we assign element to m_element in the "public" area and then print them?
Try it out, check if you can get the code to do what the quiz is asking for.
Good afternoon! I've taken a fairly long hiatus due to my work load...so I've decided to step back a couple chapters and review before continuing on. I have a question about the quiz in this chapter, and I've placed it in the comments in the following code:
Thanks for your insight, and I'm looking forward to getting back to learning C++ with you all!
-M
Because your IntPair class doesn't have any constructors and all members are public, C++ will let you initialize the members directly, as if it were a struct. Most of the time when programmers are doing this intentionally, they use the struct keyword (rather than class) and omit the public access specifier (which is redundant when you use struct).
Thanks Alex!
While I know that you haven't yet dealt with constructors (btw, I do have some prior knowledge), how is it that Line 26 (in Quiz 1a Solution) is possible since no constructors were declared/defined for class IntPair? Normally, if no constructors are defined for a class, the compiler implicitly defines a "default" constructor for it; however, in your solution, object p2 has arguments as it was initialized with two integers values!
Why wouldn't this line generate a compiler error?
Hi erad!
You can use aggregate initalization to initialize classes just like structs.
Even though it's possible, I wouldn't do it in practice. A proper constructor is way easier to get behind.
References:
* Lesson 4.7 - Structs
* Aggregate initialization: https://en.cppreference.com/w/cpp/language/aggregate_initialization
One important thing to note about the quiz:
I know that you haven't went over the private: keyword, however if you happen to declare m_first & m_second as private the below won't work.
The compiler caught this outputing:
So, by convention use struct for data only purposes because
1) a struct doesn't clean after itself
2) why a struct doesn't clean up after itself?
3) because BY CONVENTION you make it so ...
LOL
Well, to be fair, a struct inherited from C code definitely won't clean up after itself. It's only C++ structs that have that capability. So point 3 may or may not be true.
Regarding "Just like with structs, one of the easiest mistakes to make in C++ is to forget the semicolon at the end of a class declaration."
Is there a way to conceptualize this so the rule makes sense? Should we think of the definition within curly brackets being like the initialization of an object rather than a sentence?
Not that I'm aware of. But there are two lenses that might help it stick.
First, C (for structs) and C++ (for both) allow you to both define a struct/class and create one or more instances of it in the same statement:
The above code instantiates two structs of type s, named s1 and s2.
Most often, we don't do this (personally, I find it confusing, and always instantiate on a subsequent line), so it makes the semicolon seem superfluous. You can view the trailing semicolon after the definition as a signal to the compiler to say, "and don't instantiate any of these".
There's another historical reason: Classes require a semicolon at the end of the definition because structs do, and structs were inherited from C, where that was also required. Functions in older versions of C implicitly returned int unless a type was specified. So if you had a struct definition right before a function, C couldn't determine whether you intended the struct to be the return type for the function, or whether the struct was independent and the function returned an implicit int.
Some other languages, such as Java, don't require the trailing semicolon.
Excellent explanation Alex. I especially like the historical explanation. Maybe add to the lesson?
"Rule: Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions."
With the advent of classes, why use structs at all? Seems like a class can do everything a struct can do (and more, and safer). I might be oversimplifying things, but this rule reads, to me, like:
"Rule: Use a bicycle when traveling a few miles or less. Use a car when you're going far and want AC."
If you have a car, why not use it?
Hi Matt!
I agree with you.
I was thinking that maybe the class would get a constructor or operator generated by the compiler and therefore increase binary size. And this actually happens, but this also happens to structs.
It's a matter of behavior signaling.
Generally if you see a struct, you know it's being used to transport data and won't have any associated behaviors. Member access is likely to be direct, and it's not going to clean up after itself, it's not going to have virtual functions or move constructors, etc... If you see a class, you can reasonably assume it's going to at least clean up after itself.
You're certainly welcome to do otherwise, but this idiom is more common than not. Even the Google style guide recommends this:
"structs should be used for passive objects that carry data, and may have associated constants, but lack any functionality other than access/setting the data members. The accessing/setting of fields is done by directly accessing the fields rather than through method invocations. Methods should not provide behavior but should only be used to set up the data members, e.g., constructor, destructor, Initialize(), Reset(), Validate().
If more functionality is required, a class is more appropriate. If in doubt, make it a class."
As to your analogy, a better analogy is taxi color. Why are taxis generally yellow? It helps people who need rides identify which cars are taxis.
Thanks Alex for the clarification, makes sense to me.
Hi, I didn't understand how initializing classes work, If you add parameters:
MyClass initializationTest {2, 3, 4, "whhhut?"};
It goes on filling variables found in the class matrix in the order you add on the initializer line?
What if you miss some? Or maybe you want to restrict the ability to initialize certain values, how would that work?
Hi Anderson!
> It goes on filling variables found in the class matrix in the order you add on the initializer line?
Yes
> What if you miss some?
Your code won't compile
> Or maybe you want to restrict the ability to initialize certain values, how would that work?
Access specifiers (Lesson 8.3) and constructors (Lesson 8.5+)
Ok sir, thanks! I'll read those lessons, and if I still have troubles I'll drop another reply.
At: "It only defines what the class looks like." wouldn't it more precise to say: "It only defines what the object looks like."?
Technically, yes, but I don't define what an object is until later in the lesson.
Hey, there is a typo in the quiz. it says the output should be:
Pair(1, 1)
Pair(1, 2)
but it's supposed to be pair(1,1) pair(2,2) right?
Nope, the output is as intended.
If you look in the print function of the provided answer, you'll find this line:
Note that '\n' character at the end, which causes a newline to be printed after printing the Pair string.
Hey
Thank you for your valuable tutorial
can you please explain why the output is
Pair (1,1)
Pair (1,2)
instead of
Pair (1,1)
Pair (2,2)
Hi Joe and Bratan!
The output is indeed
I assume Alex was focusing on the difference in line breaks of the output provided by Bratan.
Doh. The answer is indeed as you suggest. I've fixed the typo accordingly.
Hi Alex,
May I suggest a small quiz for this lesson?
1. Create a class IntPair, which holds two public integer variables m_first and m_second. Write a set(int, int) function, which returns void, takes two integer parameters and copy them into m_first and m_second. Also, write a print() function, which prints m_first and m_second to the console.
The following code must compile:
...and produce output:
Pair(1,1)
Pair(2,2)
Suggested solution:
2. Whether IntPair should be a class?
Suggested solution:
Since structs are typically used when dealing with data-only structures, class is more suitable here, as IntPair holds functions as well.
That's a great suggestion. I've incorporated it into the lesson. Thanks for your contribution!
Hi Alex,
Can you please help me understanding this sentence:
For example, it’s fair to assume a class will clean up after itself (e.g. a class that allocates memory will deallocate it before being destroyed), but it’s not safe to assume a struct will.
Hi vysyaraju!
A struct is usually used for the single purpose of holding data. Whatever happens to that data is up to the coder.
A class is also used to hold data, but it also has functions associated with that data, this includes functions that dynamically allocate and free memory.
When you create a struct and manually allocate memory in it then you're responsible for freeing that memory.
If you have a class then that class will usually allocate that memory on it's own and upon destruction free that memory.
Yes, but it's a bit hard without having covered constructors and destructors yet.
Basically, any well-written class will have a function called a destructor that is executed when the class is destroyed. This destructor function can do any kind of cleanup necessary to return resources to the system (deallocate memory, close a file or database, disconnect from a network, etc...)
Although structs can have destructors, in practice they most often don't (if you want/need to use a destructor, use a class, not a struct). Therefore, if a struct is managing any kind of resource, it's not safe to just assume it will clean up when the struct is destroyed. It may, but it may not.
Dear Mr. Alex!
God bless!!! God Bless!!! God Bless!!!
It is not typing error that i wish God to bless you 3 times! It is a matter of satisfaction about your amazing tutorial among the once i ever seen before. I have discovered many web sites and i have downloaded many books.But only your tutorial gives me a key to get through programing from down the scratch!
I also thank you for my sister to recommend me to read your tutorial. B/s she is able to know who is the best. (she is a post doctoral researcher in computer science in Europe.)
Dear Alex You are helping my country Ethiopia (Africa)through helping me!
I like the way you treated people honestly,for all who share you their difficulties.
God bless!!! God Bless!!! God Bless!!!
Hi alex I love your tutorial I just want to ask if I will be able to create app with this knowledge because I am only aware of creating a calculator :(
You'll be able to create simple console apps. More importantly, this will give you the foundation to go out and learn other stuff, including frameworks that will help you create graphical apps.
Thank you for your answer! I want to ask if after completing this whole websites tutorials I will be able to create a button that you can click on or not... or some kind of cool visual thing. Thank you!
No -- these tutorials don't cover graphical user interfaces, because those are not part of the core C++ language. However, once you have completed these tutorials, you should have enough knowledge to learn a graphical user interface platform (e.g. QT or wxwidgets). Consider these lessons a prerequisite.
Hi Alex:
Is that possible to write a code like this:
today is an instance and it call functionA(). Then it call another functionB.
Or functionA() is not a "function"?
Yes, it is possible! If functionA() returns an object for which functionB() is a valid member function, then functionB() will be called on the return value of functionA()!
We talk about this more later in this chapter (or maybe the next one?).
Hi Alex,
what do you mean by "Unlike normal functions, the order in which member functions are defined doesn’t matter!"? I have difficulty figuring out its meaning by context.
With normal functions, a function can't call a function that's defined "below" it (without a forward declaration):
With member functions, this limitation doesn't apply:
Hi Alex,
I had the same question and I knew someone must have asked you. So, I scrolled down and saw it. It would be great if your example was shown in the lesson too.
Thanks, Have a great day.
Added to lesson. Thanks for the feedback.
Hi Alex,
Why Am I getting 1 error on uniform initialization stage when I run this program.
#include <iostream>
struct DateStruct
{
int year;
int month;
int day;
};
void print(DateStruct &date)
{
std::cout << date.year << "/" << date.month << "/" << date.day;
}
int main()
{
DateStruct today { 2020, 10, 14 }; // use uniform initialization
today.day = 16; // use member selection operator to select a member of the struct
print(today);
return 0;
}
My compiler is suggesting a ";" between "DateStruct today" and "{2020,10,14};"
What compiler are you using? If you're using an older compiler, or C++11 compatibility is disabled, uniform initialization won't work.
Sorry, I am posting a question by clicking reply to some random question.
So please clarify, Structs and classes are same?
Apart from one difference that class can clean up itself, is there no other difference?
Yes, they're essentially the same. However, by convention, how they are used typically differs, with structs being used as plain-old-data structures, and classes being used for objects.
HI alex may I ask when you say we are already using member function of std::string and std::vector ..etc why do we not need to defined a object for them like we do for class and struct ? thanks
You generally do (unless they're static). Can you give me an example?
Hi Alex!
why declaring this variable caused errors in the compilation ?
extern in this context means this is a forward declaration of variable x that is defined in some other file.
But in this program, it is not defined in some other file, so the program doesn't link.
#include<iostream>
using namespace std;
struct student
{
int rollnum;
string name;
float marks;
void print();
};
void student::print()
{
cout << rollnum << name << marks;
}
student my={2,"anum fatima",99.99};
int main()
{
my.print();
cout << endl << endl;
cout << sizeof(my);
}
hi Alex!!
there are two queries related to this little piece of code
one is , if classes provide opportunity to use data members and methods on a same platform (as being encapsulated) then with structs i can also do the same .. as i used data members declarations and use of functions in structs instead of class and my code is still working ..
second query is that why my compiler that is dev c++ giving me the size of struct 24 ?? and with what respect ??
Yes, in C++ structs and classes are almost identical. However, many people feel it was a bad decision to make structs able to act like classes, so best practice is now to use classes when you have functions, and use structs when you're data-only. This way it's clear whether your object will clean up after itself (class: yes, struct: no).
You're getting a struct size of 24 because that's apparently the sizeof(int) + sizeof(std::string) + sizeof(float), plus any memory used for alignment/padding on your machine.
sir.. why you aren't using namespace std?
Sir, please have a read of this article on using statements at your pleasure.
Hello Alex,
Pls clarify, do we declare variables or define them?
In the following quoted paragraph from above, are the sugested modification of text (or additions), placed in parentheses, correct?
"...In C++, when we define (declare) a variable of a (type corresponding to a defined) class (in short, class type), we call it instantiating the class. The variable itself is called an instance, of the class. A variable of a class type is also called an object. Just like how defining (declaring) a variable of a built-in type (e.g. int x) allocates memory for that variable, instantiating an object (e.g. DateClass today) allocates memory for that object..."
You can both declare variables and define them. Which you do depends on your intent.
Declaring a variable (via a forward declaration) simply tells the compiler that it exists, so it can do type checking. A declaration does not actually create the variable.
Defining a variable (which is what you do most of the time with variables) actually creates the variable and allocates memory for it.
A variable is only instantiated when it is defined (not declared).
If I were to declare two variables with the same name but using different classes, how would the compiler figure out which variable I am referring to when I use it in other places around the program?
No. If two variables have the same name and are in the same scope, the compiler will issue a naming collision error.
Hey Alex,
I was just wondering maybe you know what are the most important diffrences on Xcode and Visual Studio, or maybe you know some site where i can look up to it. This is really important to me so pls answer.
Thanks, Milos.
I'm not familiar with Xcode, so I couldn't say.
Also, Alex or anyone, I want to practice more programming questions on C++ from basics to advanced(oops). Can anyone share the websites? Preferably, if there are solutions to it, then will be great.
I tried to browse over net but unable to find specifically for C++ that includes control statement, loops, arrays, pointers,strings,oops etc.. questions.
Thanks in advance.
hello Deepti,
check this one https://www.hackerrank.com
and search for c++ track
try to solve the problem and if you couldn't solve it open the Discussions tab
good luck :)
Hi Alex,
I have a question in the first struct example. The function
void print(DateStruct &date)
{
std::cout << date.year << "/" << date.month << "/" << date.day;
}
has a parameter '&date'. Does this imply the parameter is passed by address? Because if the date parameter given without & and it still works
No, in this context the ampersand means the parameter is passed by reference.
hello, there is a typo in the below sentence, it says "that that" instead of "that".
Consequently, we recommend using the struct keyword for data-only structures, and the class keyword for defining objects that that require both data and functions to be bundled together.