element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Code Exchange
  • Technologies
  • More
Code Exchange
Blog C++ Tutorial - Classes
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Code Exchange to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: oneleggedredcow
  • Date Created: 6 Mar 2013 12:25 AM Date Created
  • Views 2614 views
  • Likes 1 like
  • Comments 8 comments
  • code_exchange
  • Code Exchange
  • raspberry_pi
  • code
  • rpi
  • c++
  • learnc++
Related
Recommended

C++ Tutorial - Classes

oneleggedredcow
oneleggedredcow
6 Mar 2013

Introduction

In the previous tutorial, we introduced structures, which allow you to store multiple, related values of different data types.  In this tutorial, we are going to introduce classes which are a way to store related values of different data types and functions to manipulate that data. Classes help organize your code so that related information is in the same place making it easy to find and use.

Code

From our previous example of Fruit Wars, here’s Inventory as a class, well part of it at least:

 

class Inventory

{

public:

double Money;

int GrapesCount;


 

void BuyGrapes(int quantity, double price)

{

if(price * quantity <= Money)

{

Money -= price * quantity;

GrapesCount += quantity;

}

else

{

cout << "You don't have enough money." << endl;

}

}


 

void SellGrapes(int quantity, double price)

{

if(GrapesCount >= quantity)

{

Money += price * quantity;

GrapesCount -= quantity;

}

else

{

cout << "You don't have enough grapes." << endl;

}

}

};


Classes are like a struct, but they have methods as well.  (Full disclosure, through the magic of pointers, a C style struct can have methods as well.  See the comment below about C++.)  The other difference is that in a class, the variables/methods contained within it are private by default. This means that only the class itself can use these variables/methods.  That is why we have to have the public: keyword at the top of the class, so that we can access this data from outside of the class.

 

So, you might be wondering when would I ever want to just access something from within the class?  Well, if you class had some internal state that wanted to keep, storing it in a private variable would make it impossible for someone to randomly change it out from underneath you.  Also, private variables allow you to control access to the data stored in the class, to help limit the changes that it is used incorrectly.

 

When I first implemented Inventory, I just copied and pasted the GrapesCount variable and BuyGrapes and SellGrapes methods for the other types of fruit.  This leads to a lot of duplicated code which is a very bad idea. Copied and pasted code is a problem because if there is a bug in that code, you need to hunt down every place that it was copied and pasted and fix it there.  This can be very difficult to do with a large code base, so if you find yourself copying and pasting, there is usually a better way.  In this case, I created a class called Fruit to store the quantity and handling buying and selling:

 

class Fruit

{

private:

int Quantity;


 

public:

Fruit(int initialQuantity)

{

Quantity = initialQuantity;

}


 

int GetQuantity()

{

return Quantity;

}


 

void Buy(int quantity)

{

Quantity += quantity;

}


 

void Sell(int quantity)

{

Quantity -= quantity;

}

};


This class demonstrates the use of a private variable to store the amount of fruit that we have. The only way to change the quantity is to buy and sell fruit.  Something like this:

 

Fruit apples(3);

apple.Quantity = 5;


Would result in a compiler error.  Another interesting aspect of the Fruit class is that it has a method that has the same name as the class that is called when the object is created.  This is a special method that is called a constructor.  This method is special because it has to be called when the object is created and it can only be called once.  Since Quantity is now private and can’t be directly accessed, the constructor gives the user a way to set the initial number of apples that they have lying around the house.

So, here’s what the Inventory class looks like using the Fruit class:

 

class Inventory

{

public:

double Money;

Fruit Grapes;

Fruit Blueberries;

Fruit Strawberries;

Fruit Raspberries;


 

Inventory() :

Grapes(10),

Blueberries(3),

Strawberries(0),

Raspberries(0)

{

Money = 25.00;

}


 

void Print()

{

cout << "Inventory:" << endl;

cout << "\t$" << Money << endl;

cout << "\tGrapes:       " << Grapes.GetQuantity() << endl;

cout << "\tBlueberries:  " << Blueberries.GetQuantity() << endl;

cout << "\tStrawberries: " << Strawberries.GetQuantity() << endl;

cout << "\tRaspberries:  " << Raspberries.GetQuantity() << endl;

}


 

Fruit Buy(Fruit item, int quantity, double price)

{

if(price * quantity <= Money)

{

Money -= price * quantity;

item.Buy(quantity);

}

else

{

cout << "You don't have enough money." << endl;

}


 

return item;

}


 

Fruit Sell(Fruit item, int quantity, double price)

{

if(item.GetQuantity() >= quantity)

{

Money += price * quantity;

item.Sell(quantity);

}

else

{

cout << "You don't have enough product." << endl;

}


 

return item;

}

};


Notice how the class now has a constructor as well, because we need to set the initial quantities of each of our pieces of fruit.  The colon after the constructor is where we need to call the constructors of the Fruit classes contained within our class.

 

At the beginning of the tutorial, I said that classes help organize your code by grouping together related variables and methods.  Since this is the case, it is also a great place to break your code up into multiple files.  Each class is broken up into two files: one that states the name of the class and what variables/methods it contains (*.h) and one that fleshes out the details of how each method works (*.cpp).  Here’s what the .h file looks like:

 

#ifndef FRUIT_H

#define FRUIT_H


 

class Fruit

{

private:

int Quantity;


 

public:

Fruit(int initialQuantity);


 

int GetQuantity();

void Buy(int quantity);

void Sell(int quantity);

};


 

#endif


And here is what the .cpp file looks like:

 

#include "Fruit.h"


 

Fruit::Fruit(int initialQuantity)

{

Quantity = initialQuantity;

}


 

int Fruit::GetQuantity()

{

return Quantity;

}


 

void Fruit::Buy(int quantity)

{

Quantity += quantity;

}


 

void Fruit::Sell(int quantity)

{

Quantity -= quantity;

}


What happens with multiple files is that when the compiler finds a #include statement, it copies and pastes the code from the .h file into the file.  That’s why you need all of the #ifndef and #define stuff at the top of the file.  This tells the compiler to ignore it, if it has already seen it, so that you don’t get an error about defining something multiple times.  This is a standard convention that should be used with all of the classes that you create.

 

In the .cpp file, we need to tell the compiler the containing class of the method that we wish to implement, so that is what the Fruit:: is doing.  The reason for this is that the compiler doesn’t use file names (and they don’t have to match), so this is the way that the compiler knows what logic goes with the method on the class.  It can be pretty daunting at first, but it is a standard pattern that that you can follow every time.

 

Attached is the updated code for FruitWars, using classes.

Summary

In this tutorial, we learned about classes, which are a way to group related variables and methods.

 

In the next tutorial, we will start diving into pointers, which are traditionally one of the more difficult parts of C++.  If you look at the way that the Buy method works on the Inventory class works after the introduction of the Fruit class, you will notice something a bit strange. It takes in a Fruit object and it returns a Fruit object.  In the next tutorial, we will go over why this is the case, and how we can make a slight modification to the code so that we can manipulate the class within the method.

 

If you have any questions or comments about what was covered here, post them to the comments.  I watch them closely and will respond and try to help you out.

Tutorial Index

01 - Hello Raspberry Pi

02 - Reading User Input

03 - If Statement

04 - For Loops

05 - While Loops

06 - Functions

07 - Data Types

08 - Arrays

09 - Structures

10 - Classes

11 - Pointers

12 - Dynamic Arrays

13 - Linked List

14 - Linked List Operations

15 - STL List/Vector

16 - Templates

17 - Inheritance

18 - File I/O

19 - Strings

20 - Constants

21 - Hash Tables

Attachments:
10_Classes.zip
  • Sign in to reply
  • oneleggedredcow
    oneleggedredcow over 9 years ago in reply to Former Member

    It initializes some default values.  Here's some links with more info:

    http://en.cppreference.com/w/cpp/language/initializer_list

    http://stackoverflow.com/questions/4589237/in-this-specific-case-is-there-a-difference-between-using-a-member-initialize…

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 9 years ago

    Hey guys,

     

    Could somebody explain me what this peace of code actually does?! Thanks in advance image

     

    Inventory() :

    Grapes(10),

    Blueberries(3),

    Strawberries(0),

    Raspberries(0)

    {

    Money = 25.00;

    }


    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • oneleggedredcow
    oneleggedredcow over 10 years ago in reply to oneleggedredcow

    Updated to correct the mistake.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • oneleggedredcow
    oneleggedredcow over 10 years ago in reply to Former Member

    Opps.  I started out developing it in VS, and must have zipped up the wrong set of files.  I'll correct that tonight.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 10 years ago in reply to coolbox

    It was not a compiler problem. I found the problem with the code here, which had a problem both with GCC on Raspbian and on Visual Studio 2013 on Windows 7. The problem is: _TCHAR* is not declared. The solution is to replace:

     

    int _tmain(int argc, _TCHAR* argv[])
      {
       cout.setf(ios::fixed, ios::floatfield);
       cout.precision(2);

     

    with:

     

    int main()

    {

     

    Also, on Raspbian (or presumably any Linux) must compile ALL .cpp files (with file names separated by spaces). I don't think this tutorial ever provided this info...

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube