C++ Default Arguments
Making functions more flexible with optional parameters
🎯 What are Default Arguments?
Default arguments allow you to call functions with fewer parameters than defined. If you don't provide a value, the function uses the default value you specified in the declaration.
// Function with default arguments
void greet(string name, string greeting = "Hello") {
cout << greeting << ", " << name << "!" << endl;
}
// Can call: greet("Alice") or greet("Bob", "Hi")
Output:
greet("Alice") → Hello, Alice!
greet("Bob", "Hi") → Hi, Bob!
Default Arguments Features
Flexibility
Call functions with different parameter counts
func(a), func(a,b), func(a,b,c)
Right to Left
Default values must be rightmost parameters
void func(int a, int b = 5, int c = 10)
Convenience
Reduces need for function overloading
// One function instead of multiple
Configuration
Great for optional settings and parameters
connect(host, port = 80, timeout = 30)
🔹 Basic Default Arguments
Default arguments in C++ allow functions to have predefined values for parameters when no argument is
provided. This simplifies function calls by letting you skip common values while retaining flexibility.
For example, a function like void greet(string name, string city = "Unknown") can be called with just a
name—the city defaults to “Unknown.” This reduces code duplication, improves readability, and is widely used in
constructors, mathematical functions, and APIs to provide sensible defaults while allowing customization when
needed.
#include <iostream>
#include <string>
using namespace std;
// Function with default arguments
void displayInfo(string name, int age = 25, string city = "Unknown") {
cout << "Name: " << name << endl;
cout << "Age: " << age << endl;
cout << "City: " << city << endl;
cout << "---" << endl;
}
int main() {
// Different ways to call the function
displayInfo("Alice"); // Uses both defaults
displayInfo("Bob", 30); // Uses city default
displayInfo("Charlie", 28, "New York"); // No defaults used
return 0;
}
Output:
Name: Alice
Age: 25
City: Unknown
---
Name: Bob
Age: 30
City: Unknown
---
Name: Charlie
Age: 28
City: New York
---
🔹 Mathematical Functions
Default arguments are especially useful in mathematical functions where certain parameters often remain
constant. For instance, a power function double power(double base, int exponent = 2) can
compute squares by default unless another exponent is specified. This approach minimizes repetitive code, enhances
clarity, and supports common use cases like area calculations—where a default shape might be a square. Using
defaults in math functions makes APIs intuitive and reduces the risk of errors from omitted parameters.
#include <iostream>
#include <cmath>
using namespace std;
// Power function with default exponent
double power(double base, double exponent = 2.0) {
return pow(base, exponent);
}
// Area calculation with default shape (square)
double calculateArea(double length, double width = -1) {
if (width == -1) width = length; // Square if width not provided
return length * width;
}
int main() {
cout << "5^2 = " << power(5) << endl; // Uses default exponent 2
cout << "2^3 = " << power(2, 3) << endl; // Custom exponent
cout << "Square 4x4 = " << calculateArea(4) << endl; // Square
cout << "Rectangle 3x5 = " << calculateArea(3, 5) << endl; // Rectangle
return 0;
}
Output:
5^2 = 25
2^3 = 8
Square 4x4 = 16
Rectangle 3x5 = 15
🔹 Constructor Default Arguments
Constructors in C++ often use default arguments to initialize objects with optional or missing data.
For example, a Student class constructor might set default grade ‘A’ or age 18 if values aren’t
provided. This allows flexible object creation while ensuring valid initial states. Default arguments in
constructors streamline code, reduce overloaded constructors, and improve maintainability—especially in libraries or
frameworks where object configurations vary widely but sensible defaults exist.
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
string grade;
public:
// Constructor with default arguments
Student(string n, int a = 18, string g = "A")
: name(n), age(a), grade(g) {}
void display() {
cout << "Student: " << name << ", Age: " << age
<< ", Grade: " << grade << endl;
}
};
int main() {
// Different constructor calls
Student s1("Alice"); // Uses age=18, grade="A"
Student s2("Bob", 20); // Uses grade="A"
Student s3("Charlie", 19, "B"); // No defaults
s1.display();
s2.display();
s3.display();
return 0;
}
Output:
Student: Alice, Age: 18, Grade: A
Student: Bob, Age: 20, Grade: A
Student: Charlie, Age: 19, Grade: B
🔹 Rules and Best Practices
Important rules when using default arguments:
Rules:
- Right-to-left: Default arguments must be rightmost
- Declaration only: Specify defaults in function declaration, not definition
- No gaps: Can't skip middle parameters when calling
- Compile-time: Default values must be known at compile time
// ✅ CORRECT - defaults are rightmost
void func1(int a, int b = 5, int c = 10);
// ❌ WRONG - non-default after default
// void func2(int a = 1, int b, int c = 3);
// ✅ CORRECT - calling with defaults
func1(1); // a=1, b=5, c=10
func1(1, 2); // a=1, b=2, c=10
func1(1, 2, 3); // a=1, b=2, c=3
// ❌ WRONG - can't skip middle parameter
// func1(1, , 3); // This won't compile