In this tutorial you will learn the basics of C++ and how to do conversions and indexing. This will allow you to write a simple C++ program that you will then compile. The program will be a Visual Studio console application
About this Tutorial –
Objectives –
This course is aimed at students who need to get up to speed in C++. The course introduces object-oriented concepts and shows how they are implemented in C++. The course does not require awareness or familiarity with object-oriented programming techniques, but programming experience would be useful but not necessarily required.
Audience
Students who are new to object orientation (or programming) and need to learn C++.
Prerequisites
No previous experience in C++ programming is required. But any experience you do have in programming will help. Also no experience in Visual Studio is required. But again any experience you do have with programming development environments will be a valuable.
Experience using a contemporary OO language such as Java or C# would be useful but is not required.
Contents
The C++ course covers these topics and more:
Introduction to C++: Key features of C++; Defining variables; Formulating expressions and statements; Built-in data types; Console input/output
Operators and types: Assignment; Compound Assignment; Increment and decrement operators; Const declarations; Type conversions
Going Further with Data Types: Enumerations; Arrays; Using the standard vector class; Using the standard string class; Structures
Not what you are looking? Try the next tutorial – Templates
Lab 1: Conversions
Lab 1: Conversions
Overview of Conversions
“Conversions” are when a value is converted from one data type to another
E.g. from an int to a double (or vice-versa)
E.g. from an object (such as a Person object) to a string
Etc…
This section of the chapter takes a closer look at how conversions work in C++
We explore the “built-in” conversions in the C++ language
We also explore how to define additional “custom” conversions
Implicit Conversions
An implicit conversion is one that happens automatically
i.e. you don’t have to tell the compiler to do it
C++ performs implicit conversions in the following cases:
Widening conversions, e.g. from int to double int i = 42;
double d = i; // Implicit conversion from int to double
From non-const-pointer to const-pointer Person *p = new Person("John");
const Person *cp = p; // Implicit conversion from Person* to const Person*
From pointer to void-pointer (remember, a void pointer is a special kind of pointer in C++, which can point to anything) Person *p = new Person("John");
void *pv = p; // Implicit conversion from Person* to void*
e.g. narrowing from a double to an int double d = 3.14;
int i = static_cast<int>(d);
Const Casts
const_cast
Use for conversions that relate only to const-ness
i.e. convert a non-const-pointer to a const-pointer (or vice versa) // This is a const pointer...
const Person *cp = new Person("John");
// Cast into a non-const-pointer (e.g. if you really do need to modify the object).
Person *p = const_cast<Person*>(cp);
Reinterpret Casts
reinterpret_cast
Use if you want to treat underlying types completely differently
e.g. to treat an address as a simple number (why would you need to do this...?) Person *p = new Person("John");
int addressAsNumber = reinterpet_cast<int>(p);
Dynamic Casts
dynamic_cast
Use if you want to cast a base-class-pointer to a derived type
Gives back a null pointer if the object isn't really that type
Allows you to test the real type a pointer points to
Note: doesn't work in MFC (use reinterpet_cast instead)
Because cast operators don't change original object
Example:
Define a conversion operator that converts a Person object to a string // Header
class Person
{
public:
operator string() const;
...
};
// Source
Person::operator string() const
{
// Must return correct type!
return this->name; // etc.
}
// Usage
Person person1("John");
string str1 = person1; // Implicitly calls operator string()
string str2 = (string)person1; // Can use explicit syntax if you like
string str3 = person1.operator string(); // This also works!
string str4 = static_cast(person1); // So does this!
Lab
Defining a Staff class to hold a collection of Employees
Define a class named Staff, which contains a fixed-size array of Employee objects. The constructor should take an integer specifying the array-size. int size;
Employee * employees;
static Employee dummy;
Staff::Staff(int size) : size(size)
{
employees = (new Employee[size]);
}
In the Staff class, implement operator[] to provide access to an employee at the specified index position, e.g. staff[10] should return a reference to element 10 in the underlying array. Take care of const-ness carefully. Also think what to do if index is out of range... Employee& Staff::operator[](int id) const
{
if (id < 0 || id > size)
{
return dummy;
}
else
{
return employees[id];
}
}
Also implement operator[] to provide access to an employee with a specified name, e.g. staff["Smith"] should return a reference to the first employee element whose name is "Wayne". This will involve a linear search... Also think what to do if name isn't found... Employee& Staff::operator[](string name) const
{
for (int i = 0; i < size; i++)
{
if (employees[i].GetName() == name)
{
return employees[i];
}
}
return dummy;
}
Define an index operator to get item in SafeIntArray object class SafeIntArray
{
public:
SafeIntArray(int length);
~SafeIntArray();
int& operator[](int idx) const;
int GetLength() const
{
return length;
}
private:
int length;
int * pData;
static int dummyInt; // This is what we'll return if illegal access attempt.
};
Example - Implementing Operator []
Here's the implementation of the operator[] function, plus the other members in the class #include "SafeIntArray.h"
int SafeIntArray::dummyInt = -1;
SafeIntArray::SafeIntArray(int length)
: length(length),
pData(new int[length])
{
}
SafeIntArray::~SafeIntArray()
{
delete [] pData;
}
int& SafeIntArray::operator[](int idx) const
{
if (idx < 0 || idx > this->length)
return dummyInt;
else
return this->pData[idx];
}
Example - Using Operator []
Here's some client code that shows how to use operator[] to access items in internal collection SafeIntArray myInts(4); // Contains items at indices 0, 1, 2, 3.
...
for (int i = 0; i < myInts.GetLength(); i++)
{
// Can use [] as lvalue (because it returns a reference to an item in the array).
myInts[i] = i * 100;
// Equivalent syntax:
myInts.operator[](i) = i * 100;
}
cout << "My array of integers: " << endl;
for (int i = 0; i < myInts.GetLength(); i++)
{
// Can also use [] as an rvalue.
cout << "\t" << myInts[i] << endl;
}
Overloading on const-ness
You can define 2 very similar versions of operator[]
Compiler will call this version if you use [] on a const object const int& operator[](int idx) const;
// Const function.
// Returns const ref to ensure client can't // change the returned value
The other is a non-const member function
Returns a non-const reference
Compiler will call this version if you use [] on a non-const object int& operator[](int idx);
// Non-const function.
// Returns non-const ref to allow client to change the
// returned value.
Non-integer Indexing
The parameter to operator[] doesn't have to be an int
E.g. it could be a string
Useful in scenarios such as an associative map (keys are strings, values are objects)
Trivial example: // Header
class SafeIntArray
{
public:
int& operator[](string idx) const;
...
};
// Source
int& SafeIntArray::operator[](string idx) const
{
if (idx == "zero") return pData[0];
else if (idx == "one") return pData[1];
else if (idx == "two") return pData[2];
else if (idx == "three") return pData[3];
else ... do something else ...
}
// Usage
SafeIntArray yourInts(4);
yourInts["zero"] = 1000; // Puts 1000 at index 0.
Well done. You have completed the tutorial in the C++ course. The next tutorial is
If you liked this post, please comment with your suggestions to help others.
If you would like to see more content like this in the future, please fill-in our quick survey.
Manage cookie consent
You can view this website without consenting to extra cookies. However you will need to accept the 'marketing' cookies to send messages via the contact forms & see any maps displayed on the site
Functional
Always active
Cookies necessary for the website to work.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.Cookies used to track user interaction on the site, which helps us to evaluate & improve the website.
Marketing: Forms & additional content (Marketing)
We need your permission to place ‘marketing’ cookies, so you are able to use the contact forms & see embedded content e.g. videos and maps. - - - - We have added protection to our contact forms to help prove that a human (rather than a spambot) is filling
If you would like to see more content like this in the future, please fill-in our quick survey.