C++ Fundamentals: Transitioning from C

Table of Contents

  • What is C++
  • C++ Keywords (C++98)
  • Namespaces
  • Namespace Usage
  • C++ Input & Output
  • Default Parameters
  • Function Overloading
  • References
  • Inline Functions

What is C++

C++ is an object-oriented high-level programming language that was developed based on the foundations of the C language.

C++ Keywords (C++98)

C++ contains a total of 63 keywords, while the C language has 32 keywords.

Note: The following section only shows how many keywords C++ has without providing detailed explanations for each keyword.

Namespaces

In C/C++, variables, functions, and classes (to be covered later) exist in large quantities. These identifiers all reside in the global scope, which can lead to numerous conflicts. The purpose of using namespaces is to localize identifier names and avoid naming collisions or namespace pollution. The namespace keyword was introduced specifically to address this issue.

To define a namespace, you use the namespace keyword followed by the namespace name, then a pair of curly braces {}. The members of the namespace are enclosed within these braces.

namespace Utilities
{
    // Variables, functions, and types can be defined within a namespace
    int counter = 10;
    
    int Multiply(int left, int right)
    {
        return left * right;
    }
    
    struct ListNode
    {
        struct ListNode* next;
        int value;
    };
}

// Namespaces can be nested
namespace Outer
{
    int firstValue;
    int secondValue;
    
    int Add(int left, int right)
    {
        return left + right;
    }
    
    namespace Inner
    {
        int thirdValue;
        int fourthValue;
        
        int Subtract(int left, int right)
        {
            return left - right;
        }
    }
}

Important: A namespace defines a new scope. All content within a namespace is limited to that namespace's scope.

Namespace Usage

Method 1: Using the Namespace Name with Scope Resolution Operator

int main()
{
    printf("%d\n", Outer::firstValue);
    return 0;
}

Method 2: Using using to Introduce Specific Members

using Outer::secondValue;

int main()
{
    printf("%d\n", Outer::firstValue);
    printf("%d\n", secondValue);
    return 0;
}

Method 3: Using using namespace to引入 the Entire Namespace

using namespace Outer;

int main()
{
    printf("%d\n", Outer::firstValue);
    printf("%d\n", secondValue);
    Add(10, 20);
    return 0;
}

C++ Input & Output

#include <iostream>

// std is the namespace name for the C++ standard library
// All standard library definitions are placed within this namespace
using namespace std;

int main()
{
    cout << "Hello world!!!" << endl;
    return 0;
}

Key Points:

  1. To use cout (standard output object to console) and cin (standard input object from keyboard), you must include the <iostream> header file and use the std namespace.
  2. cout and cin are global stream objects, while endl is a special C++ symbol representing a line break. All are included in the <iostream> header.
  3. The << operator is the stream insertion operator, and >> is the stream extraction operator.
  4. C++ input/output is more convenient than printf/scanf because it automatically recognizes variable types without requiring manual format specification.
#include <iostream>
using namespace std;

int main()
{
    int userAge;
    double accountBalance;
    char grade;
    
    // Automatic type recognition
    cin >> userAge;
    cin >> accountBalance >> grade;
    
    cout << userAge << endl;
    cout << accountBalance << " " << grade << endl;
    return 0;
}

Best Practices for Using the std Namespace

std is the namespace for the C++ standard library. Here are guidelines for using it appropriately:

  1. For everyday practice and exercises, using using namespace std directly is convenient and acceptable.
  2. However, this approach exposes all standard library definitions. If you define types, objects, or functions with names that conflict with the library, issues will arise. This rarely occurs in practice exercises but becomes more likely in large-scale projects. For professional development, consider using explicit namespace specification like std::cout or selectively importing specific members with using std::cout.

Default Parameters

A default parameter is a specified value assigned to a function's parameter during declaration or definition. When calling the function, if no argument is provided, the default value is used; otherwise, the specified argument is used.

void DisplayMessage(string text = "Default message")
{
    cout << text << endl;
}

int main()
{
    DisplayMessage();        // Uses default parameter
    DisplayMessage("Custom"); // Uses provided argument
    return 0;
}

Types of Default Parameters

Full Default Parameters

void ConfigureSettings(int timeout = 30, int retries = 3, bool enabled = true)
{
    cout << "Timeout: " << timeout << endl;
    cout << "Retries: " << retries << endl;
    cout << "Enabled: " << enabled << endl;
}

Partial Default Parameters

void ProcessData(int identifier, int maxCount = 100, char delimiter = ',')
{
    cout << "ID: " << identifier << endl;
    cout << "Max count: " << maxCount << endl;
    cout << "Delimiter: " << delimiter << endl;
}

Important Notes:

  1. Partial default parameters must be specified from right to left in sequence and cannot be specified intermittently.
  2. Default parameters cannot appear simultaneously in both function declaration and definition.
  3. Default values must be constants or global variables.
  4. C language does not support default parameters (not supported by compilers).

Function Overloading

In natural language, a single word can have multiple meanings, and people determine the intended meaning based on context. This concept of one name having multiple meanings is called overloading.

Function Overloading is a special case in C++ where multiple functions with similar functionality can share the same name within the same scope. These functions must differ in their parameter lists (different number of parameters, different types, or different type ordering). This feature is commonly used to handle similar operations on different data types.

Example: Different Parameter Types

int CalculateSum(int first, int second)
{
    cout << "int CalculateSum(int first, int second)" << endl;
    return first + second;
}

double CalculateSum(double first, double second)
{
    cout << "double CalculateSum(double first, double second)" << endl;
    return first + second;
}

Example: Different Number of Parameters

void LogMessage()
{
    cout << "LogMessage()" << endl;
}

void LogMessage(int severity)
{
    cout << "LogMessage(int severity)" << endl;
}

Example: Different Parameter Type Ordering

void Initialize(int id, char code)
{
    cout << "Initialize(int id, char code)" << endl;
}

void Initialize(char code, int id)
{
    cout << "Initialize(char code, int id)" << endl;
}

References

A reference is not a newly defined variable but rather an alias for an existing variable. The compiler does not allocate separate memory space for a reference; it shares the same memory space with the variable it references.

For example, a person named "John Smith" might be called "Johnny" by family and "J.S." by colleagues at work.

Syntax: Type &referenceName = referenceEntity

void ReferenceDemo()
{
    int originalValue = 42;
    int& referenceValue = originalValue;  // Define reference
    
    printf("%p\n", &originalValue);
    printf("%p\n", &referenceValue);  // Same address
}

Note: The reference type must be the same type as the reference entity.

Reference Characteristics

  1. References must be initialized at the time of definition.
  2. A variable can have multiple references.
  3. Once a reference is bound to an entity, it cannot reference a different entity.
void MultipleReferences()
{
    int data = 100;
    int& ref1 = data;
    int& ref2 = data;
    
    printf("%p %p %p\n", &data, &ref1, &ref2);  // All same address
}

Const References

void ConstReferenceDemo()
{
    const int constantValue = 50;
    // int& invalidRef = constantValue;  // Error: cannot bind non-const reference to const
    const int& validRef = constantValue;  // OK
    
    // int& literalRef = 100;  // Error: cannot bind reference to literal
    const int& literalRef = 100;  // OK
    
    double floatingPoint = 99.99;
    // int& typeMismatch = floatingPoint;  // Error: type mismatch
    const int& convertedRef = floatingPoint;  // OK (creates temporary)
}

Common Usage Scenarios

1. As Function Parameters

void SwapValues(int& left, int& right)
{
    int temp = left;
    left = right;
    right = temp;
}

2. As Return Values

int& GetCounter()
{
    static int counter = 0;
    counter++;
    return counter;
}

Efficiency Comparison: Pass by Value vs Pass by Reference

When using pass-by-value for parameters or return types, the function does not directly pass the actual variable or return the variable itself. Instead, it creates a temporary copy. Therefore, using pass-by-value is significantly less efficient, especially when dealing with large data types.

References vs Pointers

Conceptual Level: From a syntax perspective, a reference is simply an alias without its own separate memory space. It shares the same space as the entity it references.

int main()
{
    int value = 10;
    int& alias = value;
    
    cout << "Address of value: " << &value << endl;
    cout << "Address of alias: " << &alias << endl;
    return 0;
}

Implementation Level: At the underlying level, references do have memory allocated because references are implemented using pointers.

Key Differences Between References and Pointers

  1. References conceptually define an alias for a variable, while pointers store a variable's address.
  2. References must be initialized when defined, while pointers have no such requirement.
  3. Once a reference is initialized to reference an entity, it cannot reference a different entity, while pointers can point to any compatible entity at any time.
  4. There is no NULL reference, but there are NULL pointers.
  5. Size semantics differ in sizeof: For references, sizeof returns the size of the referenced type, while for pointers, it always returns the size of a memory address (4 bytes on 32-bit systems).
  6. Incrementing a reference increments the referenced entity, while incrementing a pointer moves it forward by the size of the referenced type.
  7. There are multi-level pointers, but there are no multi-level references.
  8. Access methods differ: Pointers require explicit dereferencing, while references are handled automatically by the compiler.
  9. References are generally safer to use than pointers.

Inline Functions

A function decorated with the inline keyword is called an inline function. During compilation, the C++ compiler expands the function at the call site, eliminating the overhead of function call stack frame creation. This approach improves program runtime efficiency.

Characteristics

  1. inline is a space-for-time tradeoff. When the compiler processes a function as an inline function, it replaces the function call with the function body. The trade-off is potential increase in executable size, but the benefit is reduced call overhead and improved runtime efficiency.
  2. For the compiler, inline is merely a suggestion. Diffferent compilers may implement inline differently. General recommendation: Use inline for functions that are small (not long), non-recursive, and called frequently. Otherwise, the compiler may ignore the inline suggestion.
  3. It is not recommended to separate declarations and definitions for inline functions, as this can cause linking errors. Since inline functions are expanded at compile time, they have no address, making it impossible for the linker to find them.

Tags: C++ programming object-oriented namespaces default parameters

Posted on Fri, 22 May 2026 22:01:10 +0000 by kingconnections