C++11coreintermediate
Defaulted and Deleted Functions (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
Explicitly default or delete special member functions (e.g., copy constructor).
Real-World Scenario
Prevent copying of a unique resource in a system.
Quick Snippet
snippet.cpp
class Resource { Resource(const Resource&) = delete; };Full Example
defaulted_deleted_functions.cpp
// CodeNebula - C++11 Example: Defaulted and Deleted Functions
// Compile: g++ -std=c++11 -Wall -Wextra -o example defaulted_deleted_functions.cpp
//
// This example demonstrates:
// - =default to explicitly request compiler-generated functions
// - =delete to explicitly prevent function usage
// - Controlling copy/move semantics
// - Preventing implicit conversions with =delete
#include <iostream>
#include <string>
// ============================================================
// 1. =default: Explicit compiler-generated special members
// ============================================================
class Point {
double x_, y_;
public:
Point(double x, double y) : x_(x), y_(y) {}
// Explicitly request defaults (would be suppressed by user constructor)
Point() = default; // Default constructor restored
~Point() = default; // Default destructor
// Explicitly defaulted copy operations
Point(const Point&) = default;
Point& operator=(const Point&) = default;
// Explicitly defaulted move operations
Point(Point&&) = default;
Point& operator=(Point&&) = default;
void print() const {
std::cout << "(" << x_ << ", " << y_ << ")";
}
};
// ============================================================
// 2. =delete: Non-copyable class (move-only)
// ============================================================
class UniqueResource {
std::string name_;
int handle_;
public:
UniqueResource(const std::string& name, int handle)
: name_(name), handle_(handle) {
std::cout << " Acquired: " << name_ << std::endl;
}
~UniqueResource() {
std::cout << " Released: " << name_ << std::endl;
}
// Delete copy operations
UniqueResource(const UniqueResource&) = delete;
UniqueResource& operator=(const UniqueResource&) = delete;
// Allow move operations
UniqueResource(UniqueResource&& other)
: name_(std::move(other.name_)), handle_(other.handle_) {
other.handle_ = -1;
other.name_ = "(moved)";
}
UniqueResource& operator=(UniqueResource&& other) {
if (this != &other) {
name_ = std::move(other.name_);
handle_ = other.handle_;
other.handle_ = -1;
other.name_ = "(moved)";
}
return *this;
}
void describe() const {
std::cout << " Resource: " << name_ << " [handle=" << handle_ << "]" << std::endl;
}
};
// ============================================================
// 3. =delete to prevent implicit conversions
// ============================================================
class SafeInt {
int value_;
public:
explicit SafeInt(int v) : value_(v) {}
// Delete constructors for types that would implicitly convert
SafeInt(double) = delete;
SafeInt(bool) = delete;
SafeInt(char) = delete;
int get() const { return value_; }
};
// ============================================================
// 4. =delete on free functions to prevent overloads
// ============================================================
void processInt(int value) {
std::cout << " processInt(" << value << ")" << std::endl;
}
void processInt(double) = delete; // Prevent double -> int conversion
void processInt(bool) = delete; // Prevent bool -> int conversion
// ============================================================
// 5. Non-heap-allocatable class (delete operator new)
// ============================================================
class StackOnly {
int value_;
public:
StackOnly(int v) : value_(v) {}
int get() const { return value_; }
// Prevent heap allocation
void* operator new(std::size_t) = delete;
void* operator new[](std::size_t) = delete;
};
int main() {
std::cout << "=== Defaulted and Deleted Functions ===" << std::endl;
// Defaulted functions
std::cout << "\n--- =default ---" << std::endl;
Point p1; // Uses defaulted default constructor
Point p2(3.0, 4.0);
Point p3 = p2; // Uses defaulted copy constructor
p1 = p3; // Uses defaulted copy assignment
std::cout << " p1 = "; p1.print(); std::cout << std::endl;
std::cout << " p2 = "; p2.print(); std::cout << std::endl;
Point p4 = std::move(p2); // Uses defaulted move constructor
std::cout << " p4 (moved from p2) = "; p4.print(); std::cout << std::endl;
// Non-copyable, move-only resource
std::cout << "\n--- =delete (move-only) ---" << std::endl;
UniqueResource r1("Database", 1);
r1.describe();
// UniqueResource r2 = r1; // ERROR: copy deleted
UniqueResource r2 = std::move(r1); // OK: move allowed
r1.describe();
r2.describe();
// Deleted implicit conversions
std::cout << "\n--- =delete (prevent conversions) ---" << std::endl;
SafeInt si(42);
std::cout << " SafeInt(42) = " << si.get() << std::endl;
// SafeInt bad(3.14); // ERROR: deleted
// SafeInt bad(true); // ERROR: deleted
std::cout << " SafeInt(double) = deleted" << std::endl;
std::cout << " SafeInt(bool) = deleted" << std::endl;
// Deleted overloads
std::cout << "\n--- =delete (prevent overloads) ---" << std::endl;
processInt(42);
// processInt(3.14); // ERROR: deleted
// processInt(true); // ERROR: deleted
// Stack-only object
std::cout << "\n--- =delete (stack-only) ---" << std::endl;
StackOnly s(100);
std::cout << " StackOnly on stack: " << s.get() << std::endl;
// StackOnly* p = new StackOnly(1); // ERROR: deleted
return 0;
}
// Expected output:
// === Defaulted and Deleted Functions ===
//
// --- =default ---
// p1 = (3, 4)
// p2 = (3, 4)
// p4 (moved from p2) = (3, 4)
//
// --- =delete (move-only) ---
// Acquired: Database
// Resource: Database [handle=1]
// Resource: (moved) [handle=-1]
// Resource: Database [handle=1]
//
// --- =delete (prevent conversions) ---
// SafeInt(42) = 42
// SafeInt(double) = deleted
// SafeInt(bool) = deleted
//
// --- =delete (prevent overloads) ---
// processInt(42)
//
// --- =delete (stack-only) ---
// StackOnly on stack: 100
// Released: Database
// Released: (moved)
Run command
g++ -std=c++11 -Wall -Wextra -o example defaulted_deleted_functions.cpp