CS 1337 Final Study Guide

Ace your homework & exams now with Quizwiz!

be able to identify the throw points from a code fragment

#include <iostream> #include <string> void foo(int x) { if (x <= 0) { throw std::invalid_argument("x must be positive"); } std::cout << "foo(" << x << ") called\n"; } int main() { try { foo(10); foo(-1); foo(20); } catch (const std::exception& ex) { std::cerr << "Exception caught: " << ex.what() << std::endl; } return 0; } In this example, the foo function throws an invalid_argument exception if its x argument is less than or equal to 0. This is a "throw point" in the function, where an exception may be thrown. In the main function, we call foo with three different arguments: 10, -1, and 20. The first call to foo succeeds without throwing an exception. The second call to foo triggers the invalid_argument exception at the throw point in foo, which is caught by the catch block in main and displays an error message. The third call to foo is not executed because the previous call to foo threw an exception and caused the program to jump to the catch block.

be able to understand what the access specifiers are

Access specifiers are keywords used in C++ to control the access to the class members. There are three access specifiers in C++: public, protected, and private. They are used to specify how the class members can be accessed from outside the class and from derived classes. - Public: Members declared as public are accessible from anywhere in the program. - Protected: Members declared as protected are accessible from the class itself and its derived classes. - Private: Members declared as private are accessible only from within the class itself, and not from outside or derived classes.

know what access specifiers do

Access specifiers in C++ are keywords used to specify the visibility or accessibility of class members. They control how the members of a class can be accessed by code outside of the class. There are three access specifiers in C++: public, private, and protected. Public members are accessible from anywhere in the program, including outside of the class. They define the interface of the class, which is the set of methods and variables that can be accessed by other classes or code outside of the class. Private members are only accessible within the class. They define the implementation details of the class and are not visible to code outside of the class. Private members can only be accessed by member functions of the same class. Protected members are accessible within the class and its derived classes. They are similar to private members in that they are not visible to code outside of the class, but they can be accessed by derived classes. Protected members are used to define the interface between a base class and its derived classes.

what is an exhaustive algorithm

An exhaustive algorithm, also known as a brute-force algorithm, is a type of algorithmic approach that considers every possible solution to a problem by systematically generating and testing all possible combinations of inputs or variables. The exhaustive algorithm will always find the optimal solution to a problem, but it can be computationally expensive and time-consuming. In an exhaustive algorithm, the problem space is searched systematically until a solution is found or until all possible solutions have been evaluated. This search typically involves iterating over all possible combinations of input values or variables, evaluating each combination to see if it satisfies the problem constraints or requirements, and then selecting the best solution based on a given criteria. Exhaustive algorithms can be useful for solving problems where the number of possible solutions is small and the search space is relatively simple. However, for larger problem spaces, the search can become impractical or infeasible, especially when the number of possible solutions is very large. In these cases, more efficient search strategies, such as divide-and-conquer or heuristic approaches, may be used to reduce the computational complexity of the problem. An example of an exhaustive algorithm is the brute-force search algorithm used to solve the traveling salesman problem, which involves finding the shortest possible route that visits each of a given set of cities exactly once and returns to the starting city. The brute-force algorithm systematically generates and evaluates all possible permutations of the city order until the optimal route is found. While this algorithm is guaranteed to find the optimal solution, it can be very slow and inefficient for large numbers of cities.

know the advantages of templates

Code reusability: Templates allow you to write generic code that can work with different data types. This reduces the amount of redundant code you have to write. Performance: Templates can often generate more efficient code than non-template code because the compiler can optimize the code based on the specific data types used. Flexibility: Templates provide flexibility because they can work with any data type, including user-defined types. Type safety: Templates provide strong type checking at compile-time, which helps catch errors early in the development process. Standard Library: The C++ Standard Library is heavily based on templates, and provides many powerful generic algorithms and containers that can be easily used with any data type.

know what encapsulation is

Encapsulation is a fundamental concept in object-oriented programming that refers to the practice of hiding the internal details of an object from the outside world, and exposing only what is necessary for other objects to interact with it. This is achieved by declaring the data members of an object as private or protected, and providing public member functions (also called methods) to access and modify the data in a controlled and consistent manner. Encapsulation helps in creating modular and robust programs, and also enables the concept of information hiding, where the internal representation of an object can be changed without affecting other parts of the program that use the object.

Is a queue FIFO or LIFO

FIFO

a member function of a derived class cannot have the same name as the member function of the base class

False. A member function of a derived class can have the same name as a member function of the base class. This is known as function overriding. However, the function signature (parameters and return type) must match.

private member functions in the base class can be accessed in the direct class

False. Private member functions in the base class cannot be accessed by derived classes. Only public and protected member functions can be accessed by derived classes.

if I'm doing an insertion/deletion in a linked list, how many pointers am I required to create for use during the transversal process?

For a basic linked list implementation, you don't necessarily need to create any extra pointers for traversal during an insertion or deletion operation. The traversal can be done using the head pointer and a temporary pointer variable that points to the current node being examined. For example, during insertion at the beginning of a linked list, you would create a new node and set its next pointer to point to the current head of the list. Then, you would set the head pointer to point to the new node, effectively making it the new first node of the list. You only need to create one extra pointer for the new node being inserted. Similarly, during deletion, you would traverse the list using the head pointer and a temporary pointer variable until you find the node to be deleted. Then, you would update the previous node's next pointer to point to the node after the deleted node, effectively removing it from the list. Again, you only need to create one extra pointer for the temporary pointer variable.

does using a function template require less code than overloading the function?

Function templates in C++ allow you to define a generic function that can work with different types of data. Rather than writing separate functions for every data type you want to work with, you can write a single function template that can be used with many different types. Function templates are defined using the template keyword followed by a list of template parameters in angle brackets. The template parameters can be types, non-type values, or template parameters themselves. Inside the function definition, the template parameters are used as if they were regular types or values. Function templates can be used with any data type that supports the operations used in the function. For example, the max function template can be used with integers, floating-point numbers, characters, and any other data type that supports the > operator.

know what function templates do

Function templates in C++ allow you to define a generic function that can work with different types of data. Rather than writing separate functions for every data type you want to work with, you can write a single function template that can be used with many different types. Function templates are defined using the template keyword followed by a list of template parameters in angle brackets. The template parameters can be types, non-type values, or template parameters themselves. Inside the function definition, the template parameters are used as if they were regular types or values. Function templates can be used with any data type that supports the operations used in the function. For example, the max function template can be used with integers, floating-point numbers, characters, and any other data type that supports the > operator.

what happens if an exception is thrown by a member function of a class object, what gets called?

If an exception is thrown by a member function of a class object in C++, the exception can be caught by either the member function itself or by any caller of the member function. If the exception is not caught by the member function, the C++ runtime will look for a suitable exception handler in the call stack. This means that if the member function is called by another function, that function will be given an opportunity to catch the exception before it propagates up the call stack to higher-level functions. If no suitable exception handler is found in the call stack, the program will terminate with an unhandled exception error. When an exception is thrown by a member function of a class object, any object or data structure that is destroyed as a result of the exception will have its destructors called. This includes the object itself, as well as any other objects that were created as part of the call stack. In addition, any catch blocks that are executed will have the opportunity to clean up any resources that were allocated by the member function or its callers.

if member functions act differently based on which object performs the call, what's that an example of

If member functions act differently based on which object performs the call, that's an example of polymorphism. Polymorphism allows objects of different types to be treated as if they were of the same type, which can simplify programming and increase flexibility. Polymorphism is often implemented using virtual functions, which can be overridden in derived classes to provide different behavior.

if you have a try block with throws, and you want to make sure you catch the throw, what do you need?

If you have a try block with one or more throw statements, and you want to ensure that the thrown exception is caught, you need to add a matching catch block to handle the exception. The catch block should specify the type of the exception being thrown, so that it can handle that specific type of exception. If you do not provide a matching catch block for a thrown exception, the C++ runtime will terminate the program and display an error message. Therefore, it is important to make sure that you catch all expected exceptions to prevent unexpected program termination.

what is a final member

In C++, a `final` member is a member function or member class that cannot be overridden in a derived class. When a function or class is marked `final`, it prevents any derived classes from overriding it. This is useful when you want to ensure that a certain function or class behaves in a specific way and cannot be modified by derived classes. For example, consider a class `Vehicle` that has a member function `drive()`. If we mark `drive()` as `final`, it cannot be overridden in any derived classes, ensuring that all vehicles drive in the same way regardless of their specific type.

what is a deque

In C++, a deque (short for "double-ended queue") is a container data structure that allows efficient insertion and deletion of elements at both ends of the container. A deque is similar to a vector in that it is a sequence container that stores elements in a linear fashion, but unlike a vector, a deque allows constant time insertion and deletion of elements at both the beginning and the end of the container. This is achieved by storing elements in a way that allows constant time access to both ends of the container. The deque class is provided as part of the C++ standard library and is defined in the <deque> header file.

What is a specifier in a derived class? Can it be used as the filter the base class members must pass through before becoming inherited members of the derived class?

In C++, a specifier in a derived class is a keyword used to indicate the access level of the base class members that are inherited by the derived class. The three specifiers that can be used in C++ are: public: This specifier indicates that the base class members are accessible as public members in the derived class. protected: This specifier indicates that the base class members are accessible as protected members in the derived class. private: This specifier indicates that the base class members are accessible as private members in the derived class. The access level of the base class members is determined by the specifier used in the derived class. For example, if the specifier used in the derived class is "public," then the base class members will be accessible as public members in the derived class. It's important to note that the specifier does not filter the base class members before they are inherited by the derived class. Rather, it determines the access level of the inherited members in the derived class. All public members of the base class are inherited as public members in the derived class, all protected members of the base class are inherited as protected members in the derived class, and all private members of the base class are inaccessible in the derived class.

what is a throw point

In C++, a throw point is a statement or expression in a program where an exception can be thrown using the "throw" keyword. When an exception is thrown, the program searches for a matching catch block to handle the exception, and if none is found, the program terminates with an error message. A throw point can be any statement or expression in a program, including function calls, assignments, and conditional statements, that can generate an exception. For example, a throw point can be a function call that returns an error code, or a division by zero operation that triggers a runtime error. It is important for programmers to identify and handle exceptions properly in their code, by using try-catch blocks to catch and handle exceptions thrown at the appropriate throw points. By properly handling exceptions, programmers can improve the reliability and robustness of their programs and prevent unexpected program crashes.

what are exceptions used for

In C++, exceptions are used to handle and recover from unexpected errors or exceptional situations that occur during program execution. An exception is an object that represents an error condition, such as a division by zero, an invalid input, or a memory allocation failure. When an exception is thrown using the "throw" keyword, the program searches for a matching catch block that can handle the exception. If a matching catch block is found, the program jumps to the catch block and executes the code in the block. If no matching catch block is found, the program terminates with a runtime error message. Exceptions provide a mechanism for error handling that separates the detection of errors from their handling, and allows for more robust and reliable programs. By using exceptions, programmers can write code that can gracefully handle errors and recover from unexpected situations, without having to check for errors at every step of the program execution. Exceptions can also be used to propagate errors up the call stack, allowing them to be handled by higher-level functions or by the main program. This makes it easier to write modular and reusable code, and can help to reduce the complexity of error handling in large programs. In summary, exceptions in C++ are used to handle and recover from unexpected errors or exceptional situations that occur during program execution, providing a mechanism for more robust and reliable programs.

do catch blocks of a try-catch construct have to be directly after the try-block in the source code?

In C++, the catch blocks of a try-catch construct do not have to be directly after the try-block in the source code. The catch blocks can be placed anywhere in the same function, or even in a different function or file, as long as they are within the same scope as the try-block. The catch blocks can also be nested within each other to handle different types of exceptions. So in summary, catch blocks of a try-catch construct can be placed anywhere within the same scope as the try-block, and they do not have to be directly after the try-block in the source code.

what is a catch(...) , and what does it do?

In C++, the catch(...) block is a catch block that can catch any exception, regardless of its type. The ellipsis (...) is a special syntax that indicates that the catch block can catch any exception. The catch(...) block can be useful in situations where the program needs to handle exceptions in a general way, without knowing the specific type of the exception that may be thrown. However, it is generally not recommended to use catch(...) as the default exception handler, as it may mask errors and make it harder to debug the code. So in summary, the catch(...) block is a catch block that can catch any exception, and is useful in situations where the program needs to handle exceptions in a general way. However, it is generally not recommended to use catch(...) as the default exception handler.

what are the 3 valid access specifiers

In C++, there are three access specifiers: `public`, `private`, and `protected`. - `public` members are accessible from anywhere in the program. - `private` members are only accessible from within the class in which they are defined. - `protected` members are accessible from within the class in which they are defined and from derived classes.

given a declaration, be able to identify which is the base class

In a class declaration, the base class is specified after the class name and colon, followed by the access specifier if applicable. For example: ``` class DerivedClass : public BaseClass { // class members }; ``` In this example, `BaseClass` is the base class.

should catch blocks catch all types used in throws?

In general, catch blocks in C++ should only catch the types of exceptions that they are designed to handle. It is not necessary or advisable to catch all types of exceptions that may be thrown by a program. When catching exceptions, it is important to consider the specific types of exceptions that may be thrown by a function or set of functions. If a function can throw different types of exceptions, each type of exception should be caught by a separate catch block. This allows the program to handle each type of exception in a different way, depending on the nature of the error and the requirements of the program. C++ provides a way to catch any type of exception with a single catch block using the ellipsis ... catch clause. However, it is generally not a good practice to use this catch-all clause because it can make it difficult to identify and diagnose specific types of errors in the program. The best approach is to catch only the types of exceptions that the program is designed to handle and to let any other exceptions propagate up the call stack to higher-level exception handlers.

what is inheritance definition and what it allows you to do

Inheritance is a fundamental feature of object-oriented programming that allows a new class to be based on an existing class. The existing class is called the base class or parent class, while the new class is called the derived class or child class. Inheritance allows the derived class to inherit properties and methods of the base class, such as its variables and member functions. This means that the derived class can reuse code from the base class, avoiding the need to rewrite it. In addition, the derived class can also add its own properties and methods, or override those of the base class, to provide a specialized implementation of the inherited functionality. Inheritance also allows for polymorphism, which is the ability of objects of different classes to be used interchangeably. For example, if a derived class is derived from a base class, an object of the derived class can be treated as if it were an object of the base class. This is particularly useful when designing code that needs to work with different types of objects, as it provides a way to write code that is more generic and can handle a wider variety of objects.

what mechanism in object-oriented programming languages supports the reuse of existing code by new derived code

Inheritance is the mechanism in object-oriented programming languages that supports the reuse of existing code by new derived code. With inheritance, a derived class is created by inheriting the members (fields and methods) of a base class. The derived class can then add its own members, or override existing members of the base class, to create a specialized version of the base class that fits its needs. Inheritance allows developers to create new classes that are based on existing classes, and to reuse the code from those existing classes without having to write it from scratch.

can a linked list insert/delete a node faster than it being done in an array

Inserting or deleting a node in a linked list can be faster than in an array in some cases, but not always. The time complexity of inserting or deleting a node in a linked list is O(1) if the position of the node is known (i.e., if the node is not being inserted or deleted from the beginning or end of the list). In contrast, the time complexity of inserting or deleting an element in an array is O(n), where n is the number of elements in the array, since all elements after the inserted or deleted element must be shifted to make room or close the gap. However, if the position of the node to be inserted or deleted is not known and must be searched for, the time complexity of the operation can increase to O(n) in the case of a linked list, since each node must be traversed until the desired position is found. In an array, this can also be O(n) if the element must be inserted or deleted from the middle of the array, since the elements after the insertion or deletion point must be shifted. Overall, the performance of a linked list versus an array depends on the specific use case and the nature of the data being stored.

What does iterative design mean? Can it be implemented recursively?

Iterative design is an approach to software development that involves creating a working version of a program and then refining it through a process of testing, feedback, and revision. The goal of iterative design is to create a program that is both functional and effective, while also being easy to understand and maintain. Iterative design can be implemented recursively in the sense that the process of refinement can be repeated multiple times, each time building on the work of the previous iteration. However, iterative design is typically associated with an iterative process that involves making incremental changes to the code, rather than creating completely new versions of the code through recursion. In software development, an iterative approach involves breaking down a complex problem into smaller, more manageable tasks, and then tackling each task individually, often through the use of iterative loops. This approach can be used to refine the design of a program through a series of iterations that gradually improve the program's functionality, performance, and usability. In contrast, a recursive approach involves breaking down a problem into smaller sub-problems, and then solving each sub-problem by calling the same function recursively. While recursive algorithms can be useful for solving certain types of problems, they can also be more difficult to understand and debug than iterative algorithms, especially when dealing with large or complex data structures. In summary, while iterative design and recursive algorithms share some similarities in terms of their iterative nature, they are two distinct concepts that are typically used in different ways in software development.

is a stack a FIFO or a LIFO

LIFO

know what multiple inheritance is

Multiple inheritance is a feature in object-oriented programming where a class can inherit properties and behaviors from more than one parent class. In other words, a class can have multiple base classes from which it derives its properties and methods. This allows for a greater degree of code reuse and flexibility in class design, but it can also introduce complexity and potential conflicts between the parent classes.

do throw statements have to be inside a try-block?

No In C++, the "throw" statement can be used anywhere in the code where an exception needs to be thrown. However, in order to handle the thrown exception, the "throw" statement should be placed inside a try block. The try block is followed by one or more catch blocks, which are used to catch and handle exceptions thrown by the try block. The catch blocks contain code that is executed if the corresponding exception is thrown. If no matching catch block is found for an exception, the program terminates with a runtime error. So while the "throw" statement itself does not have to be inside a try block, it is typically used in conjunction with try-catch blocks to provide error handling and recovery mechanisms in C++.

can i have a function in my derive class if it is already labeled as final?

No, if a function in a derived class is labeled as `final`, it cannot be overridden in any further derived class. Therefore, it does not make sense to add a function to the derived class if it is already labeled as `final`.

what does polymorphism mean in coding

Polymorphism is a concept in object-oriented programming that allows objects of different classes to be treated as if they are objects of the same class. It allows a program to work with objects in a more generic way, without needing to know the specific class of each object. Polymorphism is often achieved through the use of virtual functions in C++.

know what polymorphism does

Polymorphism is a feature of object-oriented programming that allows objects of different classes to be treated as if they were objects of the same class. This means that a function or method can be designed to work with objects of a certain class, and it will automatically work with objects of any derived classes as well. Polymorphism allows for more flexible and reusable code, as it eliminates the need to write separate code for each derived class.

when do recursive algorithms end

Recursive algorithms typically end when they reach a base case, which is a condition that allows the recursion to stop and return a result. In order to ensure that a recursive algorithm eventually terminates, it must have at least one base case and each recursive call must move the problem towards the base case. It's important to note that if a recursive function does not have a base case or if the recursive calls do not move the problem towards the base case, the recursion will continue indefinitely and the program will eventually run out of stack space, resulting in a stack overflow error. Therefore, it's important to carefully design recursive algorithms to ensure that they always terminate.

what is refactoring?

Refactoring is the process of modifying existing code without changing its external behavior or functionality. It involves restructuring code to make it more understandable, maintainable, and extensible, while preserving the same functionality. The goal of refactoring is to improve the quality of code without changing its behavior, making it easier to read, modify, and maintain in the future. Refactoring can involve changes to the code structure, naming conventions, variable scoping, or other aspects of the code.

know when static binding occurs

Static binding (also known as early binding or compile-time binding) occurs when the code is compiled and the address of the function to be called is resolved at compile-time. This means that the function to be called is determined at the time of compilation based on the type of the object that the function is called on. Static binding is used when the function being called is not virtual or when the function call is resolved at compile-time. It is faster than dynamic binding, but it is less flexible because the function being called cannot be changed at runtime based on the actual type of the object.

where data is always put on a stack and taken off on a stack

That statement is not completely accurate. In a stack, data is always added (pushed) and removed (popped) from the top of the stack. The "top" of the stack is the most recently added item, while the "bottom" of the stack is the least recently added item. So, data is not always "put on" the stack, but rather added to the top of the stack. Similarly, data is not always "taken off" the stack, but rather removed from the top of the stack.

given your access specifiers, which one that's used to declare members of the base class are never accessible to a derive class

The private access specifier is used to declare members of the base class that are never accessible to a derived class.

what are the 2 types of binding

The two types of binding in programming are static binding (also called early binding) and dynamic binding (also called late binding or runtime binding). Static binding is determined at compile-time and involves resolving the function or method call based on the type of the object or variable at compile-time. This means that the specific function or method that will be called is determined before the program runs. Dynamic binding, on the other hand, is determined at runtime and involves resolving the function or method call based on the actual type of the object or variable at runtime. This means that the specific function or method that will be called is determined while the program is running, based on the actual object or variable that the call is being made on.

know what it means to append a node to a list

To append a node to a list means to add a new node to the end of the list. This involves creating a new node and connecting it to the last node in the list (or to the head of the list if the list is empty). This operation is also called "insert at tail" or "insert at end" of the list. Once the new node is appended to the list, it becomes the last node and its next pointer is set to null, indicating the end of the list.

When you need to pass arguments to a base class constructor, the arguments can be passed from the derive class constructor header line using the colon operator

True

a linked list is called linked because each node is a pointer that points to the next node in the list

True. A linked list is called "linked" because it consists of a collection of nodes, where each node contains a data element and a pointer that points to the next node in the list. This creates a "link" between each node, allowing them to be traversed in a specific order.

to delete an entire linked list, normally you must transverse the list, leaving each node one by one

True. In order to delete an entire linked list, you need to traverse the list and delete each node one by one, starting from the head of the list. This is because each node in the list is dynamically allocated using the new operator, and must be deallocated using the delete operator to avoid memory leaks.

what are type parameters in a template

Type parameters in a template are placeholders for a type that will be determined at the time the template is instantiated. They allow a function or class to operate on multiple types without having to be rewritten for each type.

when a compiler finds a member function call with the version of the function it resides in the same class as the call itself, what type of binding is that?

When a compiler finds a member function call with the version of the function it resides in the same class as the call itself, it uses early binding or static binding. This is because the function to be called is known at compile-time and can be determined by looking at the type of the object used to invoke the function.

what happens when an exception is never caught?

When an exception is not caught by any catch block, it results in a program termination. The C++ runtime system looks for a matching catch block that can handle the exception thrown by the throw statement. If no matching catch block is found, the program terminates with a runtime error message, which includes information about the type of exception that was thrown. The behavior of an unhandled exception can vary depending on the operating system and runtime environment. In some cases, the program may terminate abruptly, without performing any cleanup or releasing any resources, leading to memory leaks or other problems. In other cases, the operating system may catch the exception and generate a crash report, which can help to diagnose and fix the problem. It is therefore important for programmers to properly handle exceptions in their code by including appropriate try-catch blocks to catch and handle exceptions thrown by their program. This can help to ensure that the program operates correctly and gracefully handles any exceptions that may occur during runtime.

if you have an object definition, a base class, and a derived class, and the object is declared/defined, which constructor is called first...what is the order of constructors

When an object is declared/defined from a derived class, the constructor of the base class is called before the constructor of the derived class. This is because the derived class constructor depends on the base class constructor to initialize the base class sub-object. The order of constructors in this case is: 1. Constructor of the base class is called. 2. Constructor of the derived class is called. When the object is destroyed, the order of destructors is the reverse of the order of constructors: 1. Destructor of the derived class is called. 2. Destructor of the base class is called.

when more than 1 class is derived from a base class, what do we call that?

When more than one class is derived from a base class, it is called multiple inheritance.

when searching for a node in an array, where does the search begin? what do we call the beginning

When searching for a node in an array, the search usually begins at the first element of the array, which is also known as the "head" of the array. However, the search can begin at any element of the array depending on the specific search algorithm being used.

what does it mean when the head pointer points to a null pointer

When the head pointer points to a null pointer, it means that the linked list is empty. In other words, there are no nodes in the list and the head pointer does not reference any valid node. This is often used as a way to initialize a linked list before any nodes are added to it.

C++ introduced an optional key word to help prevent subtle errors when overwriting virtual functions

Yes, C++ introduced the `override` keyword as an optional annotation for virtual functions in C++11 to help prevent subtle errors when overwriting virtual functions. The `override` keyword tells the compiler that the function is intended to override a virtual function in the base class, and if there is no such function, the compiler will generate an error. This can help catch errors such as misspelled function names or incorrect argument types.

can a program contain a regular, nontemplate version of a function and a template version of the same function?

Yes, a program can contain both a regular, non-template version of a function and a template version of the same function. The non-template version will be used when the function is called with arguments of the appropriate type, while the template version will be used when the function is called with arguments that match the template parameters.

When a new operator fails to allocate memory, does C++ throw a bad_alloc exception?

Yes, in C++, when the "new" operator fails to allocate memory, it throws a "bad_alloc" exception. The "bad_alloc" exception is a standard exception type defined in the C++ Standard Library, and is used to indicate that a memory allocation operation has failed. When the "new" operator is called to allocate memory, it first tries to allocate the requested memory block. If the allocation fails, it throws a "bad_alloc" exception. The exception can be caught using a try-catch block, and the program can then take appropriate action to handle the error condition. So in summary, when the "new" operator fails to allocate memory, C++ throws a "bad_alloc" exception, which can be caught using a try-catch block to handle the error condition.

in general design, if I have a virtual function in the base class, do i expect it to be overwritten in the derived class?

Yes, in general design, if you have a virtual function in the base class, you expect it to be overridden in the derived class. This is one of the main reasons for using virtual functions and polymorphism in object-oriented programming. By declaring a virtual function in the base class, you are essentially creating a contract or interface that specifies the behavior of that function in any derived classes. This allows for more flexibility and extensibility in your code, as you can define common behavior in the base class and then customize or extend that behavior in the derived classes by providing your own implementation of the virtual function. If a derived class does not provide its own implementation of a virtual function declared in the base class, the base class implementation will be used instead.

Can something implemented recursively be changed to be iterative?

Yes, in general, something that is implemented recursively can be changed to be iterative, and vice versa. However, the process of converting a recursive implementation to an iterative one, or vice versa, can be non-trivial and require some careful thought and design. The choice of whether to use a recursive or iterative implementation often depends on factors such as the problem being solved, the size of the input data, and the performance requirements of the program. Recursive algorithms can be elegant and easy to understand, but can also be less efficient than iterative algorithms, especially when dealing with large amounts of data or deep recursion. Iterative algorithms, on the other hand, can be more efficient, but may be harder to understand and require more code to implement. To convert a recursive implementation to an iterative one, one needs to identify the key recursive calls and their corresponding base cases, and then replace the recursive calls with loops that perform the same computation. This often involves keeping track of intermediate results in a data structure, such as a stack or queue, that can be used to simulate the call stack of the recursive function.

if you have a derived class from an existing base class, can you add new data/functions to the derive class?

Yes, you can add new data members and member functions to the derived class in addition to the inherited data members and member functions. This is one of the key benefits of inheritance: it allows you to create new classes that build upon existing ones and add new functionality while reusing code from the existing class. For example, if you have a base class `Vehicle` with a `startEngine()` function, you can create a derived class `Car` that adds new functions specific to cars, such as `shiftGears()` or `turnOnHeadlights()`. You can also add new data members to the derived class to represent characteristics specific to cars, such as `numDoors` or `make`.

can you have a function call between a try block and a catch block?

Yes, you can have a function call between a try block and a catch block in C++. The code in a try block is executed normally until an exception is thrown. If an exception is thrown, the C++ runtime searches for a matching catch block to handle the exception. If a function call is made between the try and catch blocks, and the function throws an exception that is not caught by the function itself, then the exception will be caught by the nearest catch block that matches the type of exception thrown.

know what the acronym ADT stands for in C++

abstract data type It is a theoretical concept that defines a data type in terms of its behavior or properties, rather than its implementation details. ADTs provide a way to abstract away the implementation details of a data structure and focus on its essential properties and operations. In programming languages like C++, ADTs are often implemented using classes or templates. Examples of ADTs include stacks, queues, lists, trees, and graphs.

what type of binding does the runtime code perform on virtual functions?

dynamic binding

a function that works with any data type is called an exception template

false An "exception template" is not a commonly used term in C++. Instead, the term "exception" typically refers to a type of runtime error that occurs when a program encounters an unexpected condition. Exception handling is a feature in C++ that allows a program to detect and respond to exceptions at runtime. A function that works with any data type is typically called a "function template". Function templates are a powerful feature of C++ that allow you to write generic code that can be used with different types of data. They are defined using the template keyword and a list of template parameters, which can include types, non-type values, or other templates.

look at the online example on static & dynamic binding

know what the effect of linking the base class/function virtually when you make something virtually, it normally affects pointers, when its static, it just goes with what compiles

can you have catches that follow a try-block?

no

how much memory is reserved for a function template

none

given a small template, identify symbol is the parametized types

template <typename T, int N> void printArray(T (&arr)[N]) { for(int i=0; i<N; i++) { std::cout << arr[i] << " "; } std::cout << std::endl; } In this example, the first parameter T is a type parameter, and the second parameter N is a non-type parameter of type int. The function printArray takes an array of type T with N elements, and prints each element on a separate line. The template allows the function to work with any type T and any array size N. For example, the following code instantiates the printArray template with a double array of size 3: double arr[3] = {1.2, 3.4, 5.6}; printArray<double, 3>(arr); Here, double is the type parameter, and 3 is the non-type parameter N.

does a push operation put data on a stack

true

if i have a function template, the programmer in templates, you pass data type arguments to paramatized types in template definition

true

in general, recursive programs run faster than iterative programs

true In general, recursive programs are not faster than iterative programs, and the choice of whether to use a recursive or iterative implementation often depends on factors such as the problem being solved, the size of the input data, and the performance requirements of the program. Recursive algorithms can be elegant and easy to understand, but they can also be less efficient than iterative algorithms, especially when dealing with large amounts of data or deep recursion. Recursive programs can use a lot of memory due to the overhead of maintaining the call stack, and recursive function calls can result in multiple function activations and context switches, which can be expensive in terms of time and memory. Iterative algorithms, on the other hand, can be more efficient, as they often use less memory and involve fewer function activations and context switches. Iterative algorithms can also be optimized to take advantage of specific hardware features, such as pipelining and vectorization. That being said, there are some problems that are naturally recursive in nature, and in these cases, a recursive implementation may be more intuitive and easier to understand than an iterative one. Additionally, some programming languages and compilers may optimize recursive programs and eliminate some of the overhead associated with recursive function calls, making them more efficient. In summary, while recursive programs can be elegant and easy to understand, they are not necessarily faster than iterative programs, and the choice of whether to use a recursive or iterative implementation depends on various factors and should be made on a case-by-case basis.

when you declare a template function, the prefix can contain more than 1 argument?

yes

if I have a pointer to a base class object, can it be assigned the address of a derived class object

yes, also known as upcasting, as the pointer is being cast from a derived class type to a base class type

can functions accept template parametrized types as class types? can you pass a class type as a template argument to a template parameter?

yes, yes


Related study sets

Chemistry - Industrial Chemistry - Important Industrial Processes

View Set

Virology 1+2+3+4+5+6+7+8+9+10+11

View Set