Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleted and Defaulted Functions Real World Examples

Tags:

c++

c++11

I was looking at the C++11 new features and one of them confuses me, because I can't figure out a way to use it in Real World.

It's Deleted and Defaulted Functions, does anyone have real world examples of it's usage or is it just one of those features that just adds some sugar?

like image 560
Astronaut Avatar asked Aug 29 '11 18:08

Astronaut


2 Answers

A user-declared special member function is not trivial. If a class has any nontrivial special member functions, the class is not POD. Therefore, this type is POD:

struct S {
    S() = default;
    S(int) { }
};

but this type is not POD:

struct S {
    S() { }
    S(int) { }
};
like image 147
James McNellis Avatar answered Oct 05 '22 10:10

James McNellis


struct A
{
  A(const A& arg) : data(arg.data)
  {
    do_something_special();
  }

  // by writing copy constructor, we suppress the generation of
  // implicit default constructor A::A()

  int data;
};

void foo1()
{
  A a; // does not work, since there's no default constructor
}

Let's say that our default constructor does not do anything special and is (more or less) equal to the compiler generated one. We can fix it by either writing our own default constructor (which can get tedious if our class has many non-static members), or by using the = default syntax:

struct A
{
  A() = default;
  A(const A& arg) : data(arg.data)
  {
    do_something_special();
  }

  int data;
};

Deleting functions is useful when we want to forbid using specific overloads or template specializations, or just for forbidding copying (or moving) objects.

void foo(char c) {}
void foo(int i) = delete; // do not allow implicit int -> char conversion

When you want to forbid copying (i.e. thread objects), the usual idiomatic way is to declare private copy constructor without implementation (yeah, or use boost::noncopyable). While this works for most cases, you can get into some obscure linker errors sometimes. Consider:

struct A
{
  A() = default;

  friend void foo();

private:
  A(const A&);
};

void foo()
{
  A a;
  A b(a); // results in linker error in gcc
}

Making A(const A&) deleted, we avoid potential linker errors and make our intent (disallow copying) very clear.

like image 33
Vitus Avatar answered Oct 05 '22 09:10

Vitus