basics

Bitesize Modern C++ : Smart pointers--Glennan Carnie

Do you know about smart pointers?

Bitesize Modern C++ : Smart pointers

by Glennan Carnie

From the article:

The dynamic creation and destruction of objects was always one of the bugbears of C. It required the programmer to (manually) control the allocation of memory for the object, handle the object’s initialisation then ensure that the object was safely cleaned-up after use and its memory returned to the heap. Because many C programmers weren’t educated in the potential problems (or were just plain lazy or delinquent in their programming) C got a reputation in some quarters for being an unsafe, memory-leaking language...

Bitesize Modern C++ : std::array--Glennan Carnie

Some details about arrays in C++:

Bitesize Modern C++ : std::array

by Glennan Carnie

From the article:

C++98 inherited C’s only built-in container, the array. Arrays of non-class types behave in exactly the same way as they do in C. For class types, when an array is constructed the default constructor is called on each element in the array...

The Problem, The Culprits, The Hope--Tony “Bulldozer00” (BD00) DaSilva

This is another call to all C++ programmers, it is time to change!

The Problem, The Culprits, The Hope

by Tony “Bulldozer00” (BD00) DaSilva

From the article:

Bjarne Stroustrup’s keynote speech at CppCon 2015 was all about writing good C++11/14 code. Although “modern” C++ compilers have been in wide circulation for four years, Bjarne still sees:

I’m not an elite, C++ committee-worthy, programmer, but I can relate to Bjarne’s frustration...

Bitesize Modern C++ : noexcept--Glennan Carnie

What is the use of noexcept?

Bitesize Modern C++ : noexcept

by Glennan Carnie

From the article:

We have some basic problems when trying to define error management in C:

  • There is no “standard” way of reporting errors. Each company / project / programmer has a different approach
  • Given the basic approaches, you cannot guarantee the error will be acted upon.
  • There are difficulties with error propagation; particularly with nested calls.

The C++ exception mechanism gives us a facility to deal with run-time errors or fault conditions that make further execution of a program meaningless...

Quick Q: What is a smart pointer and when should I use one?

Quick A: Pointers that helps you manage memory.

Recently on SO:

What is a smart pointer and when should I use one?

A smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to. There is no single smart pointer type, but all of them try to abstract a 'raw' pointer in a practical way.

Smart pointers should be preferred over 'raw' pointers. If you feel you need to use pointers (first consider if you really do) you would normally want to use a smart pointer as this can alleviate many of the problems with 'raw' pointers, mainly forgetting to delete the object and leaking memory.

With 'raw' C++ pointers, the programmer has to explicitly destroy the object when it is no longer useful.

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething()
// raises an exception

The simplest policy in use involves the scope of the smart pointer wrapper object, such as implemented by boost::scoped_ptr or std::unique_ptr.

void f()
{
    {
       boost::scoped_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // boost::scopted_ptr goes out of scope --
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

Note that scoped_ptr instances cannot be copied. This prevents the pointer from being deleted multiple times (incorrectly). You can, however, pass references to it around to other functions you call.

Scoped pointers are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.

A more complex smart pointer policy involves reference counting the pointer. This does allow the pointer to be copied. When the last "reference" to the object is destroyed, the object is deleted. This policy is implemented by boost::shared_ptr and std::shared_ptr.

void f()
{
    typedef std::tr1::shared_ptr<MyObject> MyObjectPtr; // Nice short alias.
    MyObjectPtr p1; // Empty
    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1=p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero.
  // The object is deleted.

Reference counted pointers are very useful when the lifetime of your object is much more complicated, and is not tied directly to a particular section of code or to another object.

There is one drawback to reference counted pointers — the possibility of creating a dangling reference:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!
Another possibility is creating circular references:

struct Owner {
   boost::shared_ptr<Owner> other;
};

boost::shared_ptr<Owner> p1 (new Owner());
boost::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!

To work around this problem, both Boost and C++11 have defined a weak_ptr to define a weak (uncounted) reference to a shared_ptr.

This answers is rather old, and so uses what was 'good' at the time, which was smart pointers provided by the boost library. Since C++11 the standard library has provided sufficient smart pointers types, and so you should favour the use of std::unique_ptr, std::shared_ptr and std::weak_ptr.

There is also std::auto_ptr. It is very much like a scoped pointer, except that it also has the "special" dangerous ability to be copied — which also unexpectedly transfers ownership! It is deprecated in the newest standards, so you shouldn't use it.

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership.
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

Handling files in C++ - using boost::filesystem

The 9th installment of my series on writing applications in C++ using Qt and boost:

Handling files - using boost::filesystem

by Jens Weller

From the article:

As part of my data is actual files (images, css, js, files...), I realized that the best way to handle those, would be to just store and load them from the file system. In the UI Qt even offers good support for displaying a folder in an Application with QFileSystemModel. But in the application...

Announcing the Meeting C++ Workshop Day!

I finally can announce the Meeting C++ Workshop day on Dec. 3rd in front of the Meeting C++ Conference:

Announcing the Meeting C++ Workshop Day!

by Jens Weller

From the article:

For the first time ever, I do organize a Workshop Day in front of Meeting C++! This is going to be a fun day giving you the knowledge of either C++ in embedded or parallelism.

While some details are still in the making, I already can announce that the speakers of the parallelism workshop are Thomas Heller, Boris Schäling and Michael Wong! The embedded workshop will feature a hands on session from KDAB "Creating HMI for embedded devices with C++ and Qt/QML" by Tobias Koenig.

...

Bitesize Modern C++ : Range-for loops--Glennan Carnie

Today is a description of a C++11 new feature:

Bitesize Modern C++ : Range-for loops

by Glennan Carnie

From the article:

If you’re using container classes in your C++ code (and you probably should be, even if it’s just std::array) then one of the things you’re going to want to do (a lot) is iterate through the container accessing each member in turn.

Without resorting to STL algorithms we could use a for-loop to iterate through the container...