C++ Interview Questions for Developers

Use our engineer-created questions to interview and hire the most qualified C++ developers for your organization.

C++

A feature-rich version of the classic C programming language, C++ is the language-of-choice for game development and the most popular operating systems – including Windows, Mac OS, and Linux.

According to the CoderPad 2023 Developer survey, C++ is the 6th most in-demand language among technical recruiters and hiring managers.

To evaluate the C++ skills of developers during coding interviews, we’ve provided realistic coding exercises and interview questions below. Additionally, we’ve outlined a set of best practices to ensure that your interview questions accurately assess the candidates’ C++ skills.

C++ example question

Anagram creator function

Implement a function which takes a list of words as an argument and finds all anagrams within the list. Anagrams are words which contain the exact same letters, like CREATED/CATERED/REACTED.

Create a vector for each group of 2 or more anagrams, then return the vector of all groups. You can put the results in any order.

Junior C++ developer interview questions

Question: What is the difference between a pointer and a reference in C++? Write a function that takes a reference to an integer and adds 5 to it.

Answer: A pointer is a variable that stores the memory address of another variable, while a reference is an alias for another variable. Here’s an example function:

void addFive(int& num) {
    num += 5;
}Code language: C++ (cpp)

Question: Explain the difference between pass by value, pass by reference, and pass by pointer in C++. Write a function that takes an integer by reference and sets it to zero.

Answer: Pass by value creates a copy of the argument, pass by reference passes a reference to the argument, and pass by pointer passes a pointer to the argument. Here’s an example function:

void setToZero(int& num) {
    num = 0;
}Code language: JavaScript (javascript)

Question: Fix the following code to properly iterate over the elements of the vector vec:

vector<int> vec = {1, 2, 3, 4, 5};
for (int i = 0; i < vec.length(); i++) {
    cout << vec[i] << endl;
}Code language: C++ (cpp)

The length function should be replaced with size. Here’s an example fix:

vector<int> vec = {1, 2, 3, 4, 5};
for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << endl;
}Code language: C++ (cpp)

Question: What is the difference between a class and a struct in C++? Write a class called Person that has a private member variable name and a public method getName that returns the name.

Answer: In C++, a class and a struct are almost identical, with the only difference being the default access level (public for struct and private for class). Here’s an example class:

class Person {
private:
    string name;
public:
    string getName() {
        return name;
    }
};Code language: C++ (cpp)

Question: Fix the following code to properly print out the elements of the array arr:

int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < arr.size(); i++) {
    cout << arr[i] << endl;
}Code language: C++ (cpp)

Answer: The arr array does not have a size method in C++. Here’s an example fix:

int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
    cout << arr[i] << endl;
}Code language: C++ (cpp)

Question: Explain the difference between the prefix and postfix versions of the increment and decrement operators in C++. Write a function that takes an integer by reference and increments it using the postfix increment operator.

Answer: The prefix increment and decrement operators increment or decrement the variable and return a reference to the updated variable, while the postfix operators return a copy of the variable before it was updated. Here’s an example function:

void postfixIncrement(int& num) {
    num++;
    num++;
}Code language: C++ (cpp)

Question: What is a reference variable in C++? Write a function that takes a reference to an integer as a parameter and adds 10 to it.

Answer: A reference variable in C++ is an alias for an existing variable. It allows the original variable to be accessed or modified using a different name. Here’s an example function:

void addTen(int& num) {
    num += 10;
}

int main() {
    int x = 5;
    addTen(x);
    cout << x << endl; // Output: 15
    return 0;
}Code language: C++ (cpp)

Question: Fix the following code to properly sort the elements of the vector vec in descending order:

vector<int> vec = {5, 2, 7, 1, 9};
sort(vec.begin(), vec.end());
reverse(vec.begin(), vec.end());
for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << endl;
}Code language: C++ (cpp)

Answer: The sort function sorts the vector in ascending order, so the reverse function needs to be used to reverse the order. Here’s an example fix:

vector<int> vec = {5, 2, 7, 1, 9};
sort(vec.begin(), vec.end(), greater<int>());
for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << endl;
}Code language: C++ (cpp)

Question: What is the difference between a stack and a heap in C++ memory management? Write a function that allocates an integer on the heap and returns a pointer to it.

Answer: The stack is used to store local variables and function calls, while the heap is used to store dynamically allocated memory. Here’s an example function:

int* allocateInt() {
    int* num = new int;
    return num;
}Code language: C++ (cpp)

Question: Fix the following code to properly concatenate the two strings “str1” and “str2”:

string str1 = "Hello";
string str2 = "world!";
string str3 = str1 + str2;
cout << str3 << endl;Code language: C++ (cpp)

Answer: The + operator is used to concatenate strings. Here’s an example fix:

string str1 = "Hello";
string str2 = "world!";
string str3 = str1 + " " + str2;
cout << str3 << endl;Code language: C++ (cpp)

Intermediate C++ developer interview questions

Question: What is inheritance in object-oriented programming? Write a class hierarchy for different types of animals.

Answer: Inheritance is a mechanism in object-oriented programming that allows a class to inherit properties and behavior from another class. Here’s an example class hierarchy for different types of animals:

class Animal {
public:
    virtual void speak() = 0;
};

class Mammal : public Animal {
public:
    virtual void giveBirth() = 0;
};

class Dog : public Mammal {
public:
    void speak() override { cout << "Woof!" << endl; }
    void giveBirth() override { cout << "Giving birth to puppies." << endl; }
};

class Bird : public Animal {
public:
    void speak() override { cout << "Chirp!" << endl; }
};Code language: C++ (cpp)

Question: Fix the following code to properly swap the values of the two integer variables x and y:

int x = 5;
int y = 10;
int temp;
temp = x;
x = y;
y = temp;
cout << x << " " << y << endl;Code language: C++ (cpp)

Answer: The temporary variable temp is used to swap the values. Here’s the fixed code:

int x = 5;
int y = 10;
int temp = x;
x = y;
y = temp;
cout << x << " " << y << endl;Code language: C++ (cpp)

Question: What is a template in C++? Write a function template that returns the maximum value in an array of any type.

Answer: A template is a mechanism in C++ that allows for generic programming. It enables writing functions and classes that can work with any type, without having to write separate versions for each type. Here’s an example function template:

template <typename T>
T maxElement(T arr[], int size) {
    T max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

int main() {
    int arrInt[] = {1, 2, 3, 4, 5};
    double arrDouble[] = {1.1, 2.2, 3.3, 4.4, 5.5};
    cout << maxElement(arrInt, 5) << endl; // Output: 5
    cout << maxElement(arrDouble, 5) << endl; // Output: 5.5
    return 0;
}Code language: C++ (cpp)

Question: What is the difference between a pointer and a reference in C++? Write a function that takes a pointer to an integer and doubles its value.

Answer: A pointer is a variable that stores the memory address of another variable, while a reference is an alias for an existing variable. Here’s an example function that takes a pointer to an integer and doubles its value:

void doubleValue(int* numPtr) {
    *numPtr *= 2;
}

int main() {
    int x = 5;
    int* xPtr = &x;
    doubleValue(xPtr);
    cout << x << endl; // Output: 10
    return 0;
}Code language: C++ (cpp)

Question: What is polymorphism in object-oriented programming? Write an example of polymorphism using function overloading.

Answer: Polymorphism is a feature of object-oriented programming that allows a single interface to be implemented in multiple ways. Function overloading is an example of polymorphism. Here’s an example:

void print(int num) {
    cout << "Printing integer: " << num << endl;
}

void print(double num) {
    cout << "Printing double: " << num << endl;
}

int main() {
    print(5);
    print(3.14);
    return 0;
}Code language: C++ (cpp)

Question: What is a linked list data structure? Write a function that inserts a new node at the end of a linked list.

Answer: A linked list is a data structure that consists of a sequence of nodes, where each node stores a value and a pointer to the next node in the list. Here’s an example function that inserts a new node at the end of a linked list:

struct Node {
    int data;
    Node* next;
};

void insertEnd(Node** head, int value) {
    Node* newNode = new Node;
    newNode->data = value;
    newNode->next = NULL;
    if (*head == NULL) {
        *head = newNode;
    } else {
        Node* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }
}

int main() {
    Node* head = NULL;
    insertEnd(&head, 1);
    insertEnd(&head, 2);
    insertEnd(&head, 3);
    Node* current = head;
    while (current != NULL) {
        cout << current->data << " ";
        current = current->next;
    }
    return 0;
}Code language: C++ (cpp)

Question: What is a virtual function in C++? Write an example of using a virtual function to implement polymorphism.

Answer: A virtual function is a function that is declared in a base class and can be overridden in a derived class. It enables runtime polymorphism. Here’s an example:

class Shape {
public:
    virtual double area() = 0;
};

class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) {
        radius = r;
    }
    double area() override {
        return 3.14159 * radius * radius;
    }
};

class Rectangle : public Shape {
private:
    double width;
    double height;
public:
    Rectangle(double w, double h) {
        width = w;
        height = h;
    }
    double area() override {
        return width * height;
    }
};

int main() {
    Shape* shape1 = new Circle(5);
    Shape* shape2 = new Rectangle(3, 4);
    cout << "Area of circle: " << shape1->area() << endl;
    cout << "Area of rectangle: " << shape2->area() << endl;
    delete shape1;
    delete shape2;
    return 0;
}Code language: C++ (cpp)

Question: Fix the following code to properly initialize the string variable “name”:

string name = "Alice";
name[0] = 'a';
cout << name << endl;Code language: C++ (cpp)

Answer: The string class in C++ does not allow direct modification of its characters. Here’s a fixed version that uses the “replace” method instead:

string name = "Alice";
name.replace(0, 1, "a");
cout << name << endl;Code language: C++ (cpp)

Question: What is a smart pointer in C++? Write an example of using a unique_ptr to manage dynamic memory.

Answer: A smart pointer is a class template that is designed to manage dynamic memory in C++. It is called “smart” because it automatically handles the allocation and deallocation of memory, helping to prevent memory leaks and other errors. Here’s an example of using a unique_ptr to manage dynamic memory:

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> ptr(new int(42));
    std::cout << *ptr << std::endl;
    return 0;
}Code language: C++ (cpp)

In this example, we create a unique_ptr object that points to an integer value of 42. The unique_ptr takes ownership of the memory and automatically deallocates it when the object goes out of scope. The dereference operator is used to access the value stored in the memory location pointed to by the unique_ptr.

Question: Fix the following code to properly initialize the elements of the 2D array “matrix”:

#include <iostream>

int main() {
    int matrix[3][3];
    for(int i = 0; i < 3; i++) {
        for(int j = 0; i < 3; j++) {
            matrix[i][j] = i * j;
        }
    }
    return 0;
}Code language: C++ (cpp)

Answer: The code has a small typo in the nested for-loop condition. Instead of checking for the value of j, it accidentally checks for the value of i again. To fix this, we can change the second condition in the nested loop to j < 3. Additionally, we can add a line to print out the contents of the matrix for verification purposes. Here’s the corrected code:

#include <iostream>

int main() {
    int matrix[3][3];
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            matrix[i][j] = i * j;
        }
    }

    // Print out the contents of the matrix
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            std::cout << matrix[i][j] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}Code language: PHP (php)

This code correctly initializes each element of the matrix array to the product of its row and column indices, and then prints out the contents of the matrix for verification.

Senior C++ developer interview questions

Sure, here are 10 questions with answers for a senior C++ developer:

Question: What is the Rule of Five in C++? Provide an example of a class that requires the Rule of Five.

Answer: The Rule of Five in C++ states that if a class requires one of the following functions: copy constructor, copy assignment operator, move constructor, move assignment operator, or destructor, then it should implement all of them. An example of a class that requires the Rule of Five is a class that manages dynamic memory. Here is an example of a class that requires the Rule of Five:

class MyString {
public:
    MyString();
    MyString(const char* str);
    MyString(const MyString& other);
    MyString& operator=(const MyString& other);
    MyString(MyString&& other) noexcept;
    MyString& operator=(MyString&& other) noexcept;
    ~MyString();

private:
    char* m_data;
    size_t m_size;
};Code language: C++ (cpp)

This class manages a character array that represents a string. It has a default constructor, a constructor that takes a C-style string as input, a copy constructor, a copy assignment operator, a move constructor, a move assignment operator, and a destructor. All of these functions must be implemented because the class manages dynamic memory.

Question: What is the purpose of the noexcept specifier in C++11? Provide an example of its use.

Answer: The noexcept specifier in C++11 indicates that a function is not expected to throw any exceptions. It is used for optimization purposes, because it allows the compiler to generate more efficient code in certain cases. Here is an example of its use:

class MyClass {
public:
    void myFunction() noexcept;
};

void MyClass::myFunction() noexcept {
    // Function body
}Code language: C++ (cpp)

In this example, myFunction is declared with the noexcept specifier, which tells the compiler that this function will not throw any exceptions. This can help the compiler generate more efficient code for this function.

Question: What is move semantics in C++? Provide an example of its use.

A: Move semantics in C++ is a feature that allows objects to be moved from one location in memory to another, rather than being copied. This can be more efficient for certain types of objects, such as those that manage dynamic memory. Here is an example of move semantics:

class MyVector {
public:
    MyVector(size_t size);
    MyVector(const MyVector& other);
    MyVector(MyVector&& other) noexcept;
    MyVector& operator=(const MyVector& other);
    MyVector& operator=(MyVector&& other) noexcept;
    ~MyVector();

private:
    int* m_data;
    size_t m_size;
};

MyVector::MyVector(MyVector&& other) noexcept
    : m_data(other.m_data), m_size(other.m_size)
{
    other.m_data = nullptr;
    other.m_size = 0;
}

MyVector& MyVector::operator=(MyVector&& other) noexcept {
    if (this != &other) {
        delete[] m_data;
        m_data = other.m_data;
        m_size = other.m_size;
        other.m_data = nullptr;
        other.m_size = 0;
    }
    return *this;
}Code language: C++ (cpp)

In this example, the MyVector class implements move semantics by providing a move constructor and a move assignment operator. When an object is moved, its data is simply transferred to the new object, rather than being copied. This can be more efficient than copying, especially for large objects.

Question: What is a lambda express in C++? Provide an example of its use.

Answer: A lambda expression in C++ is a way to define a small, anonymous function inline. It allows you to write code that is more concise and easier to read, especially when dealing with algorithms that take functions as parameters. Here is an example of its use:

std::vector<int> numbers = { 1, 2, 3, 4, 5 };
int sum = 0;

std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
    sum += n;
});

std::cout << "Sum of numbers: " << sum << std::endl;Code language: C++ (cpp)

In this example, we use a lambda expression with the std::for_each algorithm to calculate the sum of a vector of integers. The lambda expression takes an integer as input and adds it to a variable called sum, which is captured by reference. The result is printed to the console.

Question: What is RAI in C++? Explain how it can be used to improve memory safety.

Answer: RAI stands for Resource Acquisition Is Initialization, which is a design pattern in C++ that helps ensure proper resource management. The basic idea is to allocate and deallocate resources in the constructor and destructor of a class, respectively. This guarantees that the resource will be properly released, even if an exception is thrown during the lifetime of the object. For example:

class MyFile {
public:
    MyFile(const std::string& filename)
        : m_file(fopen(filename.c_str(), "r"))
    {
        if (!m_file) {
            throw std::runtime_error("Unable to open file");
        }
    }

    ~MyFile() {
        if (m_file) {
            fclose(m_file);
        }
    }

    // Other methods...

private:
    FILE* m_file;
};Code language: C++ (cpp)

In this example, the MyFile class uses RAI to ensure that the file resource is properly released when the object goes out of scope. The file is opened in the constructor, and closed in the destructor, which guarantees that it will be released even if an exception is thrown.

Question: What is the difference between std::shared_ptr and std::unique_ptr in C++? Provide an example of when you would use each.

A: std::shared_ptr and std::unique_ptr are both smart pointers in C++ that help manage dynamic memory. The main difference is that std::shared_ptr uses reference counting to keep track of how many pointers are pointing to the same object, while std::unique_ptr does not allow multiple pointers to the same object. Here is an example of when you would use each:

// Using std::unique_ptr
std::unique_ptr<MyClass> p1(new MyClass());
std::unique_ptr<MyClass> p2 = std::move(p1);

// Using std::shared_ptr
std::shared_ptr<MyClass> p3(new MyClass());
std::shared_ptr<MyClass> p4 = p3;Code language: C++ (cpp)

In this example, we create two instances of MyClass using std::unique_ptr and std::shared_ptr. With std::unique_ptr, we can transfer ownership of the object from p1 to p2 using std::move. This ensures that there is only one pointer to the object at any given time. With std::shared_ptr, we can create multiple pointers to the same object, which is useful when we need to share ownership of the object among multiple parts of our program.

Question: What is a move constructor in C++? When is it invoked?
Answer:
A move constructor is a special type of constructor that is used to move the resources owned by an object into another object of the same type. It is invoked when an object is being constructed using an rvalue (i.e., a temporary object). The move constructor is used to efficiently transfer the resources owned by the temporary object into the new object, rather than making a copy of the resources.

Question: What is perfect forwarding in C++? Provide an example.
Answer:
Perfect forwarding is a technique used to forward arguments to another function or constructor, while preserving their value category (i.e., whether they are an lvalue or an rvalue). This allows the function or constructor being called to take ownership of the arguments, while avoiding unnecessary copies or moves. An example of perfect forwarding in C++ is the std::forward function, which is used to forward arguments to another function or constructor. For example, consider a template function that takes an argument by reference, and needs to forward that argument to another function:

template<typename T>
void some_function(T&& arg) {
    // Forward the argument to another function
    other_function(std::forward<T>(arg));
}Code language: C++ (cpp)

In this example, the std::forward function is used to forward the arg argument to the other_function function, while preserving its value category.

Question: What is the difference between a const pointer and a pointer to a const in C++? Provide an example of when you would use each.
Answer:
A const pointer is a pointer that cannot be modified to point to a different object, while a pointer to a const is a pointer that can be modified to point to a different object, but cannot be used to modify the object it points to.

You would use a const pointer when you want to ensure that the pointer itself is not modified, for example when declaring a function parameter that should not modify the object being pointed to:

void some_function(const int* const ptr);Code language: C++ (cpp)

In this example, the const pointer ptr cannot be modified to point to a different object, and the object it points to cannot be modified.

You would use a pointer to a const when you want to ensure that the object being pointed to is not modified, but the pointer itself can be modified to point to a different object, for example when passing a read-only object to a function:

void some_function(const int* ptr);Code language: C++ (cpp)

In this example, the pointer ptr can be modified to point to a different object, but the object it points to cannot be modified.

Question: What is the difference between the new and malloc functions in C++? When should you use one over the other, and why? Can you provide an example of each?

Answer: The new operator and the malloc() function are both used for dynamic memory allocation in C++, but they work differently and have some important differences.

The new operator is a type-safe way to allocate memory dynamically in C++. It not only allocates memory but also constructs objects in that memory. new returns a pointer to the newly allocated memory, which can be assigned to a pointer variable of the appropriate type. For example:

int* p = new int;Code language: C++ (cpp)

This allocates a single int on the heap and returns a pointer to it, which is stored in the variable p.

The malloc() function, on the other hand, is a C-style function that simply allocates a block of memory of a specified size. It does not call the constructor for any objects that may be stored in that memory block. malloc() returns a void* pointer to the allocated memory, which must be cast to the appropriate type before it can be used. For example:

int* p = (int*)malloc(sizeof(int));Code language: C++ (cpp)

This allocates a single int on the heap and returns a pointer to it, which is stored in the variable p.

One important difference between new and malloc() is that new throws an exception if the allocation fails, whereas malloc() returns a null pointer. This means that you need to check the return value of malloc() to make sure the allocation was successful, but with new, you can use a try-catch block to handle any allocation failures.

Another important difference is that new calls the constructor for any objects stored in the allocated memory, and delete calls the destructor when the memory is deallocated, whereas malloc() and free() do not. This means that if you are working with objects that require initialization and cleanup, you should use new and delete instead of malloc() and free().

In general, it is recommended to use new and delete for dynamic memory allocation in C++, since they are type-safe and handle object initialization and cleanup automatically. However, malloc() and free() can still be useful in certain situations, such as when working with legacy code or when interoperating with C libraries that use malloc() and free().

More C++ interview question resources

1,000 Companies use CoderPad to Screen and Interview Developers

Best interview practices for C++ roles

To conduct successful C++ interviews, it is important to consider several factors, such as the candidate’s experience and the specific engineering position. To ensure an effective interview experience, we recommend incorporating the following best practices:

  • Develop technical questions that relate to real-world business scenarios within your company. This approach will engage the candidate effectively and help you assess their fit for your team.
  • Encourage collaboration by inviting the candidate to ask questions throughout the interview.
  • Errors happen! Make sure candidates can handle C++ exceptions gracefully.

In addition, it is important to follow standard interview practices when conducting C++ interviews. This includes tailoring the complexity of the questions to match the candidate’s skill set, providing prompt updates on their application status, and giving them the opportunity to ask questions about the evaluation process and working with you and your team.