Core Object-Oriented Programming Concepts in C++
Abstraction Explained
Abstraction is the act of representing essential features without including background details or explanations. It is used to reduce complexity and allow for efficient design and implementation.
Types of Abstraction in Programming
There are two main kinds of abstractions in programming languages:
- Process Abstraction: A subprogram that provides a way to continue a process without revealing the underlying details.
- Data Abstraction: A technique to separate the interface of a data type from its implementation details. It provides limited information and hides background details.
What is an Abstract Data Type (ADT)?
An Abstract Data Type (ADT) is a data structure, often in the form of a record or class, which includes subprograms (methods) that manipulate its data.
ADT Language Design Considerations
A key design consideration for ADTs is providing controlled access. ADTs must offer functions (methods) allowing users to modify internal values. While these methods are typically public, the data members themselves should remain private to maintain encapsulation.
Differences Between C++ Structs and Classes
In C++, structs and classes are very similar. The primary difference lies in default access modifiers:
- In classes, member variables, methods, and base classes default to
private
access. - In structs, member variables, methods, and base classes default to
public
access.
In C (distinct from C++), a struct
is simply an aggregate collection of public data members. It lacks class-like features such as methods, constructors, or inheritance. However, it’s possible to simulate object-oriented programming (OOP) in C by defining functions that take a pointer to a struct as their first parameter.
Why Use Accessors (Getters) Over Public Types?
Using accessor methods (getters) to retrieve private data is generally preferred over making data members public due to several advantages:
- Reliability: Accessors can include validation or logic before returning a value, ensuring data integrity.
- Encapsulation: Data is hidden and protected from direct external modification, adhering to encapsulation principles.
- Controlled Access: Private data can only be accessed through the class’s own methods (including accessors), maintaining control over how data is read.
Friend Functions and Classes in C++
A friend function is a function declared by a class using the friend
keyword. Although not a member of the class, it has access to the private and protected members of the class that declared it as a friend.
Similarly, a friend class is a class whose members have access to the private and protected members of another class that declared it as a friend.
Where Java Methods and Classes Are Defined
In Java, all methods must be defined within a class. Classes themselves are defined within a single syntactic unit, typically a .java
file.
Challenges of Defining ADTs in C
A significant challenge when defining ADTs in C is its lack of built-in support for private data types. The core purpose of ADTs involves hiding implementation details (information hiding) via private members and controlled public interfaces, which C does not enforce directly.
Why Was Encapsulation Developed for Large Programs?
Encapsulation was developed to address challenges in large-scale software development. Key motivations include:
- Organization: Encapsulation allows grouping logically related data and functions (types) into manageable units (like classes or modules).
- Access Control: It provides mechanisms to control access to the entities within an encapsulation, protecting internal state.
- Recompilation Efficiency: Encapsulation helps minimize the impact of changes; modifications within an encapsulation might not require recompiling code that uses it, provided the public interface remains stable.
Key Features of Object-Oriented Languages
Object-oriented languages typically exhibit three characteristic features:
- Data Abstraction: Provided through encapsulation, which bundles the properties (data) and behaviors (functions/methods) of an object.
- Inheritance: The ability for a new class (subclass or derived class) to inherit properties and methods from an existing class (superclass or base class).
- Dynamic Binding (Polymorphism): The ability to determine which method implementation to execute at runtime, often associated with inheritance and method overriding. This allows code to operate on objects of different types through a common interface.
Class Variables vs. Instance Variables
The main difference lies in how they are shared among objects:
- Class Variables (Static Variables): There is only one copy of a class variable, shared by all instances (objects) of the class. Changes made by one object are reflected in all others.
- Instance Variables (Member Variables): Each object has its own personal copy of instance variables. Their values are independent across different objects.
Understanding Polymorphic Variables
A polymorphic variable is a variable (often a pointer or reference) declared with a base class type that can reference (or point to) objects of that base class and objects of any of its derived classes (descendants).
What is Method Overriding?
Method overriding occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. The overriding method in the subclass has the same name, signature (parameters), and return type (or a compatible one) as the method in the parent class. Its purpose is to provide an operation customized for objects of the subclass.
Abstract Methods and Classes Defined
- An abstract method is a method declared without an implementation (no method body). It only defines a signature or protocol that subclasses must implement. In C++, this is often a pure virtual function.
- An abstract class is a class that includes at least one abstract method (or pure virtual function in C++). Abstract classes cannot be instantiated directly; they serve as base classes for other classes to inherit from.
Deallocating C++ Heap Objects
C++ objects allocated on the heap (using new
) are typically deallocated explicitly using the delete
operator, which often invokes the object’s destructor.
Pure Virtual Functions in C++
A pure virtual function (or pure virtual method) in C++ is a virtual function declared using = 0;
syntax. It makes the class abstract and requires any non-abstract derived class to provide an implementation for it.
How Java Objects Are Deallocated
Java objects are deallocated automatically by the Java Virtual Machine’s (JVM) garbage collector. When the garbage collector determines an object is no longer reachable, it reclaims the memory. Optionally, the JVM may call the object’s finalize()
method just before reclamation, but reliance on finalize()
for resource cleanup is generally discouraged.
Advantage of Dynamic Binding Example
Consider a base class Shape
with a virtual method draw()
. Derived classes like Circle
and Square
inherit from Shape
and override the draw()
method to provide their specific drawing logic. If you have a collection of Shape
pointers (polymorphic variables), you can iterate through them and call draw()
on each pointer. Dynamic binding ensures that the correct draw()
method (Circle::draw
or Square::draw
) is executed at runtime based on the actual object type being pointed to. Without dynamic binding, you would need complex conditional logic (like if/else
or switch
statements based on type) to achieve the same result, making the code less flexible and harder to maintain.
The Single Variable Type in Smalltalk
In essence, all Smalltalk variables are references to objects. The type system is dynamic; the type compatibility is checked at runtime when messages (method calls) are sent to objects, not based on static variable declarations.
When C++ Method Calls Are Statically Bound
A C++ method call is statically bound (resolved at compile time) unless the method is declared virtual
and the call is made through a pointer or reference to an object. Calls to non-virtual methods, or calls to virtual methods made directly on an object instance (not via a pointer or reference), are typically statically bound.
C++ Class Member Concepts
Object Copies of Member Variables
Each object of a class has its own copy of the class’s non-static member variables (instance variables).
Shared Access with Static Variables
If a member variable is declared static
, all instances (objects) of that class share a single copy of that variable.
Calling Static Member Functions
If a member function is declared static
, it may be called using the class name and scope resolution operator (::
) even before any instances of the class are created.
Instance Member Variable Description
An instance variable is a non-static member variable within a class. Each object (instance) of the class gets its own separate copy of these variables.
Static Member Variable Description
A static member variable is declared with the static
keyword. There is only a single copy of this variable shared among all objects of the class.
Static Member Variable Declaration
Static member variables are declared inside the class declaration (usually in the header file).
Static Member Variable Definition
Static member variables must be defined (and optionally initialized) outside the class declaration, typically in the implementation file (.cpp).
Static Member Function Limitations
A member function declared static
may not access any non-static data members or call non-static member functions directly within that class (as it’s not associated with a specific object instance).
Default Initialization of Static Variables
C++ automatically initializes all uninitialized static member variables to zero (or its equivalent for the type).
Calling a Static Member Function
Assuming a class named Numbers
has a static member function declared as static void showTotal();
, the correct way to call it is: Numbers::showTotal();
Access Restrictions in Static Functions
A static
member function cannot access any non-static member variables in its own class directly.
Accessing Static Variables Before Object Creation
A static
member variable may be accessed before any objects of the class have been created.
Existence of Static Member Variables
A static member variable comes into existence in memory before any instances of its class are created, typically when the program starts.
Limitations of Static Member Functions
A static member function can only directly access other static member variables and static member functions of the same class. It does not have access to the this
pointer.
Static vs. Instance Member Function Calls
A static member function can be called using the class name (ClassName::functionName()
) even if no objects exist. An instance member function requires an object instance to be called (objectName.functionName()
).
Friend Functions and Classes
Friend Function Definition
A friend function is not a member of a class but is granted access to the private and protected members of the class that declares it as a friend.
Friend Function Membership
If class X declares function f as a friend, function f does not become a member of class X.
Friend Keyword Placement
If class Y is a friend of class X (meaning Y’s members can access X’s private/protected members), the friend class Y;
declaration appears within class X’s declaration.
Caution Against Friend Classes
Making an entire class a friend of another class is often discouraged because it grants all member functions of the friend class access to the private and protected members, potentially weakening encapsulation more than necessary.
Forward Declaration Purpose
A forward declaration (e.g., class MyClass;
) tells the compiler that a specific class exists and will be fully declared later in the program. This is often needed when classes reference each other.
Copy Operations and Constructors
Memberwise Assignment Explained
Memberwise assignment is the default behavior when one object is assigned to another object of the same class using the assignment operator (=
). Each data member of the source object is copied to the corresponding data member of the destination object.
Copy Constructor Definition
A copy constructor is a special constructor that is called automatically when a new object is created and initialized with the data of an existing object of the same class.
Compiler-Provided Defaults
If you do not provide your own, the compiler will automatically generate a default version for: Constructor, Destructor, and Copy Constructor (and the copy assignment operator).
Copy Constructor Parameter Type
C++ requires that a copy constructor’s parameter be a reference to an object of the same class, typically a const
reference (e.g., ClassName(const ClassName& other)
).
When Copy Constructor is Called
A copy constructor is called in situations like:
- Initializing an object with another object:
Rectangle box2 = box1;
orRectangle box2(box1);
- Passing an object by value to a function.
- Returning an object by value from a function.
Memberwise Assignment Example (Initialization)
One instance when memberwise assignment (via the copy constructor by default) occurs is when one object is initialized with another object’s data, such as: Rectangle box2 = box1;
Memberwise Assignment Example (Assignment)
Another instance when memberwise assignment (via the copy assignment operator by default) occurs is when one existing object is assigned the value of another using the =
operator: box2 = box1;
When to Avoid Memberwise Assignment
Default memberwise assignment should NOT be used (and custom copy constructor/assignment operator should be implemented) when an object contains members that are pointers to dynamically allocated memory. The default copy would only copy the pointer address, leading to multiple objects pointing to (and potentially trying to delete) the same memory (shallow copy).
Identifying a Copy Constructor
The compiler identifies a copy constructor because its signature typically has a single parameter that is a reference (usually const
) to an object of the same class type as the constructor’s class.
Default Copy Constructor Action
A class’s default copy constructor performs memberwise assignment (a shallow copy).
Need for Explicit Copy Constructor
When objects contain pointers to dynamically allocated resources, it is crucial to create an explicit copy constructor (and copy assignment operator, and destructor – Rule of Three/Five) to perform a deep copy.
Operator Overloading
Redefining Standard Operators
C++ allows you to redefine the way standard operators work when used with class objects. This is called operator overloading.
Reason for Operator Overloading
A good reason for overloading an operator is to enable it to work intuitively with programmer-defined data types (classes), mimicking its behavior with built-in types where appropriate.
Making Copy Constructor Parameters Constant
It is good practice to make a copy constructor’s parameter constant by specifying the const
keyword in the parameter list (e.g., const Pet& other
). This prevents the constructor from accidentally modifying the source object.
Default Behavior for Assignment
If you do not furnish an overloaded assignment operator (operator=
), an automatic memberwise copy will be performed when one object is assigned to another existing object.
Overloading the Assignment Operator (=)
Assuming a class named Pet
, the correct member function prototype to overload the =
operator would typically be: Pet& operator=(const Pet& other);
(Returning a reference allows chaining assignments).
Function Call Notation for Overloaded Operators
If dog
and cat
are instances of the Pet
class, which has overloaded the =
operator, the statement dog = cat;
can be rewritten in function call notation as: dog.operator=(cat);
Disadvantage of `void` Return for `operator=`
If an overloaded assignment operator returns void
, it cannot be used in multiple assignment statements (e.g., a = b = c;
) or other expressions where the result of the assignment is needed.
Purpose of the `this` Pointer
The this
pointer is a built-in pointer, automatically available within a class’s non-static member functions. It always points to the specific instance of the class that invoked the function call.
Functions Receiving the `this` Pointer
The this
pointer is automatically passed as an implicit argument to all non-static member functions.
Operators That Cannot Be Overloaded
Certain operators cannot be overloaded in C++, including the scope resolution operator (::
), member access dot (.
), pointer-to-member (.*
), sizeof
, and the conditional operator (?:
).
Overloading Square Brackets (`[]`)
A reason to overload the square brackets []
operator is to create classes that behave like arrays, allowing access to elements using array-like syntax.
Definition of Operator Overloading
When you redefine the way a standard operator works when it is used with class objects, you have overloaded the operator.
Function Name for Overloading `+`
To overload the +
operator, you would write a function named operator+
.
The `this` Pointer and Dynamic Memory
The this
pointer is a special built-in pointer available to a class’s non-static member functions. It points to the object instance itself, which is particularly useful in functions that manipulate the object’s members, including those dealing with dynamic memory allocation related to the object.
Unchangeable Aspect of Overloaded Operators
When you overload an operator, you cannot change the number of operands (arity) the operator takes, nor its precedence or associativity.
Implicit Object in Binary Operator Overloading
Assume Animal
overloads +
and =
. In the statement wildcat = cat + tiger;
(where all are Animal
instances), the object calling the operator+
function is cat
(the left-hand operand).
Argument in Binary Operator Overloading
In the statement wildcat = cat + tiger;
, the object passed as an argument into the cat.operator+
function is tiger
(the right-hand operand).
Dummy Parameter for Postfix Unary Operators
When overloading unary operators like ++
or --
, the use of a dummy int
parameter in the function signature (e.g., operator++(int)
) indicates to the compiler that this overload is for the postfix version of the operator (e.g., obj++
). The prefix version has no parameter (e.g., operator++()
).
Procedural vs. Object-Oriented Programming
Two Common Programming Methods
Two common programming paradigms are: Procedural programming, which is centered around functions or procedures, and Object-Oriented programming, which is centered around objects.
Software Entity with Data and Functions
A class is a blueprint or template for creating objects. An object is a software entity that contains both data (attributes) and functions/procedures (methods) that operate on that data.
Encapsulation Definition
Encapsulation is an object’s ability to bundle its data and the methods that operate on that data together, often hiding the internal details from the outside world.
Construct for Creating Objects in C++
In C++, the class
(and also struct
) is the construct primarily used to define blueprints for creating objects.
Class as a Blueprint Analogy
Yes, classes are analogous to a blueprint, while objects are analogous to the houses built from that blueprint.
Class Fundamentals
Class vs. Structure Differences
The main differences between class
and struct
in C++ are:
- Default Access: Members (data and functions) of a
class
areprivate
by default. Members of astruct
arepublic
by default. - Default Inheritance: Inheritance from a
class
isprivate
by default. Inheritance from astruct
ispublic
by default.
Syntactically, they are declared using the keywords class
and struct
respectively.
Default Access Specification in a Class
The default access specification for a class member is private
.
Reason for Private Member Variables
You should declare class member variables private
to enforce encapsulation and data hiding. This protects the internal data from direct modification by code outside the class, preventing accidental corruption and allowing the class to maintain its invariants through controlled access via public member functions (getters and setters).
Order of Private/Public Declaration
False. You do not have to declare all private members before public members; they can be interspersed, although grouping them by access specifier is common practice.
Class Member Default Access
True. Class members are private by default.
Struct Member Default Access
False. Members of a struct are public by default in C++.
Similarity of C++ Classes and Structs
True. Classes and structures in C++ are very similar, differing mainly in default access and inheritance types.
Grouping Private Members
False. All private members of a class do not have to be declared together, although it’s good practice.
Grouping Public Members
False. All public members of a class do not have to be declared together, although it’s good practice.
Typical Access for Data and Functions
Normally, data member variables of a class are declared private
, whereas member functions intended for external use are declared public
.
Access for Member Functions
A member function of a class can be private or public (or protected). To allow the function to be accessed by code outside the class, it must be declared public
.
Analyzing a Function Header
For the function header void Circle::getRadius()
:
- The name of the function is
getRadius
. - The class the function is a member of is
Circle
.
Scope Resolution Operator
The ::
symbols are referred to as the scope resolution operator.
Correct Use of Scope Resolution Operator
Assuming RetailItem
is a class with a member function void setPrice(double p)
, the correct definition header using the scope resolution operator is: void RetailItem::setPrice(double p)
Accessing Private Members Externally
An object’s private member variables are accessed from outside the object indirectly via its public member functions (like getters and setters).
Calling a Member Function
If soap
is an instance of the RetailItem
class, the statement that properly calls the setPrice
member function is: soap.setPrice(1.49);
Meaning of `const` After Member Function
In double getWidth() const;
, the const
keyword signifies that the getWidth
member function promises not to change any data members of the object on which it is called. It can be called on const
objects.
Accessing Member Functions from `main`
To access a public class member function from the main
function (or any code outside the class) using an object instance, you use the dot operator (.
).
Initial Value of Uninitialized Members
When an object like box
is created (instantiated), its non-static member variables like width
and length
will initially contain indeterminate (garbage) values unless they are explicitly initialized (e.g., by a constructor).
Class vs. Instance
A class is a user-defined data type (a blueprint). An instance of the class is an actual object of that data type that exists in memory during program execution.
Mutator Function
A mutator (or setter) is a member function designed to store a value in a private member variable or otherwise change the state (an attribute) of an object.
Accessor Function
An accessor (or getter) is a member function designed to retrieve (get) the value stored in a private member variable without modifying the object’s state.
Order of Definition and Declaration
False. A class must be declared before objects of that class can be defined.
`const` Keyword Placement
True. When marking a member function as const
, the const
keyword must appear in both the function declaration (in the class definition) and the function definition header (in the implementation).
Pointers to Class Objects
True. It is legal and common to define a pointer to a class object.
Avoiding `cin`/`cout` in Member Functions
One should generally avoid using cin
or cout
directly within class member functions (unless the class’s specific purpose is I/O) because it tightly couples the class to console I/O. This makes the class less reusable. Instead, classes should provide member functions to get data (accessors) and set data (mutators), leaving the actual I/O operations to the application code that uses the class.
Object Definition Terminology
Defining a class object is often called the instantiation of a class.
Dynamic Allocation of Objects
True. You can use the new
operator to dynamically allocate an instance of a class on the heap.
Rationale for Private Member Variables
Declaring class member variables private protects them from direct manipulation by external code. This prevents invalid data from being assigned and ensures data integrity is maintained through controlled access via public methods (encapsulation).
Accessing Private Variables Externally
Code outside the class accesses private member variables indirectly by calling the class’s public member functions (accessors and mutators).
When Member Functions Should Be Private
A member function should be private if it performs internal helper tasks necessary for the class’s operation but is not intended to be called directly by code outside the class. This hides implementation details and prevents misuse.
Calling Private Member Functions Externally
False. A private member function cannot be called from a statement outside the class, even if it’s in the same program file.
Accessing Members Through Pointers
Members of a class object may be accessed through a pointer to the object by using the arrow operator (->
) (e.g., objectPtr->member
).
Separation of Interface and Implementation
Class Specification File
The class specification file is typically a header file (conventionally ending in .h
or .hpp
) that contains the class declaration (interface).
Class Implementation File
The class implementation file is typically a source file (conventionally ending in .cpp
) that contains the definitions (implementations) of the class’s member functions.
Declaration: Interface or Implementation?
The declaration of a class defines its interface (what members it has and how they can be accessed).
Function Definitions: Interface or Implementation?
The function definitions provide the implementation (how the member functions actually work).
File for Class Declaration
The class declaration normally goes in the header (.h
or .hpp
) file.
File for Member Function Definitions
The member function definitions are normally stored in the implementation (.cpp
) file.
Memory Allocation: Definition or Declaration?
The definition of an object (e.g., MyClass myObject;
) or dynamic allocation (new MyClass()
) sets aside memory for it. The class declaration itself does not allocate memory for objects.
Compiling Specification File
False. The class specification (header) file is typically not compiled directly but is included (#include
) by implementation files and other source files that use the class.
Compiling Implementation File
True. The class implementation file (.cpp
) must be compiled to generate object code for the member functions.
Include Guard Statement
An example include guard statement is: #ifndef RECTANGLE_H
Purpose of Include Guards
The purpose of include guards (using #ifndef
, #define
, #endif
) is to prevent the contents of a header file from being included and processed more than once within a single compilation unit (.cpp file), avoiding redefinition errors.
Function of `#ifndef RECTANGLE_H`
The directive #ifndef RECTANGLE_H
tells the preprocessor to check if a macro named RECTANGLE_H
has not been previously defined. If it hasn’t, the preprocessor processes the code between the #ifndef
and the corresponding #endif
. The subsequent #define RECTANGLE_H
ensures that on any further attempt to include the same header in the same compilation unit, the #ifndef
condition will be false.
File Separation Requirement
False. While separating declaration (.h) and definition (.cpp) is standard practice for non-trivial classes, C++ does not strictly require it. Simple classes and template classes are often fully defined within the header file. The program using the class (containing main
) is typically in its own .cpp file.
Inline Functions, Constructors, and Destructors
Inline Member Function Definition
An inline member function is a function whose definition (body) is provided directly inside the class declaration within the header file. Alternatively, the inline
keyword can be used with a function definition outside the class declaration (though compilers often make their own inlining decisions).
Inline Function Performance Considerations
True/False (Context Dependent): While inlining can reduce function call overhead for very small functions, potentially increasing performance, excessive inlining or inlining large functions can lead to code bloat (larger executable size), which might negatively impact cache performance and overall speed, especially on systems with limited memory or paging. Modern compilers are often better at deciding when to inline than manual hints.
Avoiding Inline Functions
False/Misleading: Inline functions are not generally avoided. Small, frequently called functions (like simple getters/setters) are prime candidates for inlining as the potential performance gain from reduced call overhead can outweigh any code size increase. However, blindly inlining complex functions is usually detrimental.
Function Called Automatically on Object Creation
A constructor is automatically called when an object is created.
Member Function with Same Name as Class
A constructor is a member function that has the same name as the class.
Function for Initialization
A constructor is useful for performing initialization or setup routines when a class object is created.
Constructor Naming Rule
True. A constructor must have the same name as its class.
Multiple Constructors
False. A class can have multiple constructors (overloaded constructors) as long as they have different parameter lists.
Single Default Constructor
True. A class can have only one default constructor (a constructor that can be called with no arguments). This can be user-defined or compiler-generated.
Compiler-Supplied Default Constructor Only
False. You can define your own default constructor. If you define *any* constructor, the compiler will *not* generate a default one automatically.
Constructor Declaration Requirement
False. A constructor does not have to be declared for every class. If no constructors are declared, the compiler may provide a public default constructor.
Constructor Return Type
False. A constructor must *not* be declared with a return type, not even void
.
Automatic Constructor Call
True. A constructor is automatically called each time an object of the class is created.
Single Destructor
True. A class can have only one destructor.
Destructor Naming Rule
True. A destructor must have the same name as the class, preceded by a tilde (~
).
Destructor Arguments
False. A destructor cannot have parameters (arguments).
Destructor Declaration Requirement
False. A destructor does not have to be declared for every class. If none is declared, the compiler may provide a public default destructor.
Destructor Return Type
False. A destructor must *not* be declared with a return type, not even void
.
Automatic Destructor Call
True. A destructor is automatically called each time an object goes out of scope or is explicitly deleted.
Constructor Return Type (Reiteration)
True. Constructors cannot have a return type.
Destructor Return Type (Reiteration)
True. Destructors cannot have a return type.
Multiple Destructors (Reiteration)
False. A class can have only one destructor.
Constructor Return Type (Reiteration 2)
True. Constructors may not have a return type.
Constructor Arguments
False. Constructors can take arguments.
Destructor Arguments (Reiteration)
True. Destructors cannot take arguments.
Destructor Return Value
False. Destructors may not have a return value (or return type).
Constructor Default Arguments
True. Constructors can have default arguments, following the standard C++ rules for default arguments.
Member Function Overloading
True. Member functions (including constructors, but not destructors) may be overloaded.
Constructor Overloading Restriction
False. Constructors may be overloaded.
Conflicting Default Constructors
True. A class cannot have both a constructor with no parameter list and another constructor whose arguments *all* have default values, as this would create ambiguity for calling a constructor with no arguments.
Constructor Calls for Object Arrays
False. When an array of objects is defined, the appropriate constructor is called for *each* element in the array.
Single Default Constructor/Destructor
True. A class may only have one default constructor (callable with no arguments) and only one destructor.
Passing Arguments to Array Element Constructors
An initializer list may be used when defining an array of objects to pass arguments to the constructors of the individual elements (e.g., MyClass arr[2] = { MyClass(1), MyClass(2) };
or using aggregate initialization if applicable).
Function Name with Tilde Prefix
A destructor has the same name as the class but is preceded with a tilde (~
).
Function Called Automatically on Object Destruction
A destructor is a member function that is automatically called when an object is destroyed (goes out of scope or is deleted).
Member Function with No Return Type, Can Have Arguments
Constructor.
Member Function with No Return Type, No Arguments
Destructor.
Destructor Name Start Character
Destructor function names always start with a tilde (~
).
Constructor Requiring No Arguments
A constructor that requires no arguments (or has default values for all arguments) is called a default constructor.
Private Member Functions Possibility
Yes. Member functions can be private (or protected).
Public Member Data Possibility
Yes. Member data can be public, although it often violates good encapsulation principles.
Different Data Values in Objects
Yes. If you have two Cat
objects, Frisky and Morris, they can (and usually do) have different values in their non-static member data.
Header for a `Cat::Meow` Function
The header for a member function Meow
belonging to class Cat
, which takes no parameters and returns void
, would look like: void Cat::Meow()
(in the definition) or void Meow();
(in the declaration within the class).
Encapsulation and Private Data
True. Encapsulation in C++ usually involves making a class’s data members private.
Public Member Functions
True. A C++ class’s member functions intended for external use are usually public, but helper functions can be private or protected.
Default Argument Rules
True. If a constructor (or any function) parameter has a default argument, all parameters located to its right in the parameter list must also have default values.
Omitting Argument Names
True. Argument names can be omitted in a function declaration (prototype), but they are generally required in the function definition (implementation) if the arguments are used within the function body.
Functions Inside Class Declaration
True. Function bodies (definitions) can appear within a class declaration, making them implicitly inline.
Default Access in Struct vs. Class
False. In a C++ struct
, members are public by default. In a class
, members are private by default.
Global Object Constructor Timing
True. The constructor for a global object is invoked before the main()
function begins execution.
Global Object Destructor Timing
True. The destructor for a global object is called automatically after the program terminates (i.e., after main()
has exited or exit()
is called).