Cpa – C++ Certified Associate Programmer Free Sample Questions
Description
Covers unary, binary and ternary operators, control flow and exception statements, function basics and overloading, pointer declarations and arithmetic, and classes, constructors and namespaces.
20 free sample questions275 in the full practice test
A software engineer is developing a custom memory pool for an embedded system with tight memory constraints. The goal is to avoid standard library overhead. The following code snippet is part of the memory manager. What is the primary issue with this implementation?
Answer and explanation
Correct answer: B
The core issue is memory alignment. new char[POOL_SIZE] returns a pointer that is guaranteed to be aligned for char, but not necessarily for any arbitrary type T. If T has stricter alignment requirements (e.g., double or a struct with specific members), placing it at an unaligned address pool + offset invokes undefined behavior. A robust memory pool must account for alignof(T) when calculating offsets.
Question 2
A developer is building a high-performance logging framework. To avoid ambiguity and ensure type safety, they want to prevent implicit conversions from integers to their custom LogLevel enum class. Which code snippet correctly achieves this?
Answer and explanation
Correct answer: C
The enum class (scoped enumeration) is specifically designed to provide strong type safety. It prevents implicit conversions to and from integer types. Programmers must explicitly cast if a conversion is needed. The call setLogLevel(0) will fail to compile because 0 is an int and cannot be implicitly converted to the LogLevel type.
Question 3
A junior developer wrote the following function to process a configuration file. During a code review, a senior developer points out a potential issue with exception safety. What is the primary problem?
#include
#include
#include
void processConfig(const char* filename) {
std::ifstream* file = new std::ifstream(filename);
if (!file->is_open()) {
delete file;
throw std::runtime_error("Cannot open file");
}
// Assume this function can throw an exception
parseData(*file);
delete file;
}
Answer and explanation
Correct answer: B
This code violates the RAII (Resource Acquisition Is Initialization) principle. If parseData(*file) throws an exception, the function's execution stack is unwound, and control transfers to the nearest catch block. The final delete file; line is skipped, resulting in a memory leak. The correct approach is to manage the resource with an object whose destructor handles cleanup, such as creating the std::ifstream object on the stack or using a smart pointer like std::unique_ptr.
Question 4
Multiple answers
An architect is designing a system with different types of user accounts (e.g., AdminUser, GuestUser, PowerUser), all derived from a common User base class. The system needs a factory function that can create any type of user account based on a string identifier and return a pointer to the base User class. However, the architect wants to prevent clients from accidentally slicing the objects if they are copied. Which of the following are necessary steps to achieve this design? (Select TWO)
Answer and explanation
Correct answers: A, C
Question 5
Consider the following macro definition. What is the output when the main function is executed?
#include
#define SQUARE(x) x * x
int main() {
int a = 4;
std::cout << SQUARE(a + 1);
return 0;
}
Answer and explanation
Correct answer: B
The preprocessor performs a direct text substitution. The line std::cout << SQUARE(a + 1); expands to std::cout << a + 1 * a + 1;. Due to operator precedence, the multiplication 1 * a is performed first. The expression evaluates as 4 + (1 * 4) + 1, which is 4 + 4 + 1, resulting in 9. To fix this, the macro should be defined with parentheses: #define SQUARE(x) ((x) * (x)).
Question 6
True or False: In C++, if a class has a user-defined destructor, the compiler will no longer implicitly generate a default constructor.
Answer and explanation
Correct answer: B
This statement is false. The presence of a user-defined destructor does not prevent the compiler from generating a default constructor. However, if a user declares any constructor (e.g., a copy constructor or a constructor with parameters), the compiler will then refrain from generating the default constructor.
Question 7
Case Study: A Game Development Studio
A game development studio is creating a new 3D rendering engine. The engine needs to manage various types of game objects, such as Player, Enemy, and Scenery. Each object has a position in 3D space, but also contains type-specific data and behavior. For performance reasons, all game objects are stored in a single std::vector and are updated and rendered in a tight loop.
Current Situation
The initial design has a GameObject base class with virtual functions for update() and render(). When a GameObject is destroyed (e.g., an enemy is defeated), its memory must be reclaimed. The team has observed occasional crashes and memory corruption issues during long gameplay sessions, particularly when large numbers of objects are created and destroyed rapidly.
Requirements
The system must correctly manage the lifecycle of all derived GameObject types.
When an object is deleted through a GameObject* pointer, the complete object, including derived parts, must be destroyed.
The design should be extensible to allow for new GameObject types in the future without modifying the main game loop.
The cause of the memory corruption must be eliminated.
Proposed Code Snippet
class GameObject {
public:
// Constructor and other members...
virtual void update() = 0;
virtual void render() = 0;
// Missing destructor
};
class Enemy : public GameObject { ... };
// In game loop:
delete allGameObjects[i]; // i is the index of the object to be removed
Which change is most critical to fix the memory corruption and meet the design requirements?
Answer and explanation
Correct answer: C
The most critical issue is the lack of a virtual destructor in the polymorphic base class GameObject. When delete is called on a base class pointer (GameObject*), if the destructor is not virtual, only the base class destructor is invoked. This leads to undefined behavior because the derived class's destructor (e.g., ~Enemy()) is never called, and resources owned by the derived class are not released. This is a classic cause of memory corruption and leaks in C++. Declaring the base class destructor as virtual ensures that the entire object hierarchy is destroyed correctly.
Question 8
What is the decimal value of the variable result after the following code executes?
int flags = 0b10110; // 22 in decimal
int mask = 0x1A; // 26 in decimal, 0b11010 in binary
int result = flags & mask;
Answer and explanation
Correct answer: C
The bitwise AND operation (&) compares the bits of two numbers. A bit in the result is set to 1 only if the corresponding bits in both operands are 1. flags (0b10110) mask (0b11010)
result(0b10010)
The binary value 0b10010 is calculated as (1 * 16) + (0 * 8) + (0 * 4) + (1 * 2) + (0 * 1), which equals 16 + 2 = 18.
Question 9
A programmer needs to write a function that accepts an array of integers and its size, and it must modify the original array elements by doubling their value. Which function signature is the most appropriate and conventional C++ approach for this task?
Answer and explanation
Correct answer: C
In C++, when an array is passed to a function, it decays into a pointer to its first element. To modify the original array's contents, the function must accept a pointer to the element type. int* arr is the idiomatic way to declare a parameter that accepts an array of integers. The function can then use pointer arithmetic or array subscripting to access and modify the elements. A void return type is appropriate as the modifications are done in-place.
Question 10
What is the final value of x after the following code snippet is executed?
int x = 10;
int y = 5;
x = (y > 3) ? ( (y 0) ? ++y : --y );
Answer and explanation
Correct answer: B
The expression is evaluated as follows:
The outer condition (y > 3) is checked. Since y is 5, this is true.
The true-branch of the outer ternary is evaluated: ( (y < 10) ? y++ : y-- ).
The inner condition (y < 10) is checked. Since y is 5, this is true.
The true-branch of the inner ternary is evaluated: y++.
The post-increment operator y++ returns the current value of y (which is 5) and then increments y to 6.
The value 5 is assigned to x.
Register free for 10 more questions
Or unlock all 275 CPA-21-02 questions with explanations, timed mode and flashcards.