C++ midterm review

C++ midterm review

COMP 345 C++ midterm review

C++ midterm review


Slide Set 1:

1. program structure

  • C++ is a superset of C

    • Main function is the program driver
    • Free functions
    • Data structures
    • A C program is valid C++ program
  • Classes encapsulate other functions: Object-oriented

  • The main function is a free function, not a class member

  • Only simplistic programs are self-contained into one file

    • C++ is a language that specifies programming structures and includes only
      basic data structures and operators
    • Most programs require the use of libraries
    • Complier will compile the library’s code and the program’s code, then
      the linker will link them
    • Unlike Java, a single C++ file can contain many classes/functions/data
      structures.
    • This leads to what is called physical design, i.e. decisions as to what entities are grouped within/across files.
  • multiple files programs Aside from having to use libraries, large programs need to be split into different files for various reasons:

    • Speed up compilation: Upon changes to the code, the compiler will recompile only the files that had a change.
    • Increase organization, decrease browsing time: Physically splitting your code along logical lines will make it easier to browse through the code to locate classes, functions, etc.
    • Facilitate code reuse: Modular physical design allows for grouping related entities and separating them from less related ones. Each group can then be logically designed to be reusable across different projects. Reused code can be fixed, fixing all projects that use it.
    • Split coding responsibilities among programmers: For really large projects, several programmers are involved. The larger are the program files, the more likely it is that several programmers are changing the same file simultaneously.

2. compilation unit

  • In C++, a compilation unit is a file (.cpp)

  • A file may contain several functions, data structures, or classes (unlike Java)

  • Each compilation unit is compiled individually into an object file

  • The object files typically have cross-references to other object files

  • The linker then attempts to resolve cross-references between the object files to form the unique executable file.

  • Each component is a group of highly cohesive and highly coupled elements

  • Cohesion: The degree to which the elements of a module belong together in the achievement of a common goal.

  • Cohesion is increased if:

    • The functionalities embedded in a module have much in common.
    • The composing elements carry out a small number of related activities, by avoiding coarsely grained and/or unrelated sets of data.
  • Advantages of high cohesion:

    • Increased understandability of modules (simpler, fewer operations).
    • Increased maintainability, because changes in one module require fewer changes in other modules.
    • Increased reusability, because application developers will find the component they need more easily among the cohesive set of operations provided by the module.
  • Coupling: the degree to which an element relies on other elements for its operation

    • Coupling is not a desired quality, but is a side-effect of defining different elements to carry a common task
    • Much related to cohesion: good modules exhibit high cohesion and high coupling
    • Coupling between modules is what really needs to be avoided
  • Disadvantages of high coupling:

    • A change in one module forces a ripple effect of changes in other modules
    • Assembly of modules requires more effort due to the increased inter-module
      dependency
    • A module might be harder to reuse and/or test because dependent modules must be included

3. header/cpp files

  • header File (.h file)

    • Contains class declaration with free functions and operators declarations
    • Useful to programmers, as it is overview of a component that omits
      implementation details
  • Source File (.cpp file)

    • Contains free/member function definitions
    • The .cpp file is a compilation unit
  • General rules:

    • There should be a one-to-one relationship between a given .cpp file and a corresponding .h file, and they should have the same name.
    • The .cpp file “#includes” its corresponding .h file.
    • A .cpp file should never be “#included”, as it effectively merges two compilation units together.
  • cpp files contain the executable code, i.e. function definitions

    • Function definitions:
      • Functions - main() function, free functions, member functions
      • Operators - free operators, member operators

4. includes

  • Two types to use #include
    • #include "mymodule.h"
      • Quotes indicate a user-defined module
      • The compiler will find it in your project directories
    • #include <mymodule.h>
      • < > indicate predefined library header file
      • The compiler will find it in the library directories
      • Using different search paths

5. redundant includes

  • Use preprocessor directives

    • Instructs the compiler to read a header file only once
  • two ways for fname.h :

    1
    2
    3
    4
    5
    6
    #ifndef FNAME_H
    #define FNAME_H
    ...
    //Content of header file
    ...
    #endif
    • #pragma once

6. namespaces

  • Namespace: Collection of name definitions inside of a program, potentially across different files

  • For example, namespace “std” is common in libraries. Has all standard library definitions we need

    1
    2
    #include <iostream>
    using namespace std;
    • Includes entire standard library of name definitions
      1
      2
      3
      #include <iostream>
      using std::cin;
      using std::cout;
    • Can specify just the objects we want
    • Can be more efficient, as it avoids including things we don’t use
  • This is one reason why the use of using NS::name directive is advocated over using namespace NS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    {
    using namespace NS1;
    myFunction();
    }
    {
    using namespace NS2;
    myFunction();
    }
    //or
    {
    using NS1::MyFunction();
    myFunction();
    }
    {
    using NS2::MyFunction();
    myFunction();
    }
  • global namespace

    • All code goes in some namespace
    • Unless specified, code belongs to the global namespace
      • No need for using directive
      • Global namespace always available
      • But there is no way to “turn it off”
      • Thus, global namespace is prone to name clashes
  • the same namespace needs to be declared in both .h and .cpp files

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // In the header file         
    namespace Space1
    {
    void greeting();
    }
    //In the implementation file (definitions):
    namespace Space1
    {
    void greeting()
    {
    cout << "Hello from namespace Space1.\n";
    }
    }
  • global vs. unnamed namespace

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>
    using namespace std;

    namespace {
    const int i = 4; // this is local
    }

    int i = 2; // this is global

    int main() {
    cout << i << endl; // ERROR, i is ambiguous
    return 0;
    }

Slide Set 2:

1. structs and classes as data types

  • User-defined data types using struct (as in C), as well as class (object-oriented programming)

    • Both are allowed in the same program
    • In fact, they are almost equivalent, but struct was kept for backward compatibility
    • A struct can have data members, methods, constructors, destructors, etc
    • One difference is that a struct sets its members as public by default

2. variable initialization

  • Declarations can include an optional initialization, which can use different syntactical forms:

    1
    2
    3
    4
    Type a1 {v};
    Type a2 = {v};
    Type a3 = v;
    Type a4(v);
  • All of these are widely used and apparently equivalent.

  • However:

    • Some are restricted to use in certain situations.
    • Only the first one is universally usable, and is actually safer, as it implicitly does some checking of the value passed versus the specified type.
      1
      2
      int a1 = 1.5; //allowed using truncation
      int a1 {1.5}; //not allowed, as type checking is enforced
  • Default initialization: variable is constructed with no initializer.

    1
    2
    3
    4
    5
    //For basic types, the previous value held in the memory space is kept.
    //For objects, the default constructor is called.
    int x;
    std::string s;
    classA *objAv1 = new classA;
  • Value initialization: variable is constructed with an empty initializer.

    1
    2
    3
    4
    5
    //For basic types, the value is zero-initialized.
    //For objects, each member is value-initialized.
    int x{};
    std::string s{};
    classA objA = classA();
  • Direct initialization: variable is constructed using explicit constructor arguments.

    1
    2
    3
    4
    5
    //For basic types, no constructors, but constructor call syntax can be used.
    //For objects, the corresponding constructor is called
    int x(4);
    std::string s("hello");
    classA objA(value1,value2,value3);
  • Copy initialization: Variable is created using the value(s) from an existing object of the same type, or uses a converting sequence if available. Applies only to named objects.

    1
    2
    3
    std::string s = "hello";
    classA objAv1; classA objAv2(objAv1);
    classA objAv3 = objAv1;
    • Copy initialization is implicitly used when passing and returning objects by value.
  • List initialization: Initializes an object from a braced initialization list.

    1
    2
    3
    std::string s{'a', 'b', 'c'};
    int n1{1}; // direct-list-initialization
    int n2 = {1}; // copy-list-initialization
  • Reference initialization: Binds a reference to an object.

    1
    2
    char& c = a[0]
    int i1; int& iref = &i1;
    • Reference initialization is used implicitly when a value is passed by reference or a reference is returned from a function.
  • Aggregate initialization: Initializes an aggregate from braced initialization list. It is list initialization but applied to aggregates.

    • Simply stated, an aggregate is either:
      • an array
      • an object of a class that has only public members and no constructors
      • Definition of an aggregate varies between standards.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        char a[3] = {'a', 'b'};
        int i[3] = {1,2,3};

        class aggrB{
        int x, y;
        }

        class aggrA{
        int a, b, c;
        aggrB b;
        }

        aggrA a1 = {1,2,3,{4,5}};

3. implicit/explicit type coercion

  • type coercion: implicitly or explicitly changing the type of variables or values, and this makes C++ a weakly typed language.

int var = 2.99; // 2 is assigned to var!

static_cast, dynamic_cast
  • Different kinds of Explicit type casting
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    static_cast<Type>(expression)
    //General-purpose type casting
    static_cast<double>(intVar)

    const_cast<Type>(expression)
    //Cast-out “constantness”

    dynamic_cast<Type>(expression)
    //Runtime-checked conversion of pointers and references within a single class hierarchy. Used for downcasting from a superclass to a subclass

    reinterpret_cast<Type>(expression)
    //Implementation-dependent casting, performs a binary copy and assigns the new type to the resulting binary copied value. Highly unsafe and error-prone.
* upcasting/downcasting
  • static_cast makes a static (compile-time) type cast, but correct runtime behavior cannot be verified.

  • Use dynamic_cast to downcast into a subclass

  • dynamic_cast works on pointers

  • Does runtime checking to verify that the cast is successful

  • Also deals with polymorphic types and virtual methods at runtime

4. conversion sequences

  • Two things can be used in a conversion sequence:

    • conversion constructor: a constructor that takes a value of a type and creates an object of another type. A::A(int){...}

    • conversion operator: a member operator that has the name of a type.
      A::operator int(){...}

  • If you don’t want your constructors or operators to be used in a conversion sequence, you have to declare them as explicit in the class declaration

    • explicit B(int);
    • explicit operator bool() const;

5. pointers

  • A pointer variable contains the memory address of a portion of memory that in turn contains a specific value.

    1
    2
    3
    int i = 99;
    int* p = &i;
    cout << *p << endl;
  • Two operators on pointers:

    • Dereferencing operator: *, e.g. *p refers to the object pointed to by the pointer.
    • Address operator: &, e.g. &i refers to the address of the first memory cell holding a value.
  • pointer assignment: p1 = &v1;, p2 = p1;

  • value assignment: *p2 = *p1;

  • If pointers are declared in a function

    • The pointer is managed as a local variable
    • The value pointed to is dynamically allocated/deallocated,
  • allocated with new operator, deallocated wih the delete operator.

  • Allocated on the heap (also known as freestore) through the runtime system’s interaction with the operating system.

    1
    2
    3
    4
    5
    int *p;
    p = new int(5); //allocate memory
    ... //Some processing...
    delete p; //deallocate memory
    p = NULL; //prevents dangling pointer errors

6. pointer artithmetic

  • Can perform arithmetic operations on pointers
  • Used to navigate arrays (covered later)
    1
    2
    int *d;
    d = new int[10];
  • d refers to: `address of new int[10]``
  • d + 1 refers to: address of new int[10] + 1*sizeof(int)(Note: type of int is 4 bytes, so sizeof(int) is 4 bytes.)
  • d + 2 refers to: address of new int[10] + 2*sizeof(int)
  • d[i] == *(&d[0]+i) == *(d+i)

7. pointers and const

  • two sepatate meanings/usages of const
    • Specify the constantness of the pointer
    • Specify the constantness of the value pointed to.
      1
      2
      3
      4
      5
      6
      7
      int x;

      int * p1 = &x; // non-const pointer to non-const int
      const int * p2 = &x; // non-const pointer to const int
      int * const p3 = &x; // const pointer to non-const int

      const int * const p4 = &x; // const pointer to const int

8. void/wild/dangling/null pointers

  • void pointer: a pointer that is allowed to be pointing to a value of any type.

    • disadvantage: need to cast them specifically in order to use them.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      // void* data
      void increase (void* data, int psize){

      if ( psize == sizeof(char) ){

      char* pchar; pchar=(char*)data; ++(*pchar); }

      else if (psize == sizeof(int) ){

      int* pint; pint=(int*)data; ++(*pint); }

      }

      int main (){
      char a = 'x';
      int b = 1602;
      increase (&a,sizeof(a));
      increase (&b,sizeof(b));
      cout << a << ", " << b << '\n';
      return 0;
      }
  • wild pointer: a pointer that points to an arbitrary memory location.

    • This is most often due to an uninitialized pointer declaration
    • like int *x;
  • wild pointer can lead:

    • Segmentation fault:

      • pointing to an address that is not accessible by the program’s process
      • pointing to an address that contains read-only data
    • Arbitrary value:

      • pointing to a valid address that contains a valid but arbitrary integer value
  • dangling pointer: a pointer that used to point to a valid memory area, that has now been potentially reassigned to another usage.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int* func(){
    int num = 1234; // num is local to func
    return &num; // func returns pointer to num
    }

    void func(){
    ClassA *objA = new ClassA();
    delete(objA); // *objA is deallocated

    // objA is now a dangling pointer
    // Dereferencing will still appear
    // to work, until the memory is used
    // for something else

    }
  • null pointer: a pointer that points nowhere

    • int* x = nullptr;
    • int* y = NULL;
    • int* z = 0;
    • Dereferencing a null pointer is a compilation error : safer pointer usage.
  • Pointers should be initialized as null pointers.

  • Dangling pointers should be assigned to null.

  • Check for null pointer is then a good way to know if a pointer is valid or not.

* stack/heap/new/delete
* arithmetics

9. references

  • A reference is in fact an “alias” for a memory space.

  • Terminology: the reference is an alias to a referent (the value pointed to).

  • Both the reference and the referee represent the same value/object.

  • such as int& r{v1};, return &r

  • references are often used to pass parameters or even return a value.

10. smart pointers (NO)

11. parameter passing

  • Parameters can be passed to a function:
    • by value
    • by pointer
    • by reference
      • cannot pass NULL, as a reference cannot be NULL

12. strings

  • two types:
    • C-style character strings
      • char greeting[6]={'H','e','l','l','o','\0'}; terminated by \0 (a null character)
      • char greeting[] = "Hello";
      • <cstring>
    • string class type introduced with Standard C++

Slide Set 3:

1. input/output streams

  • C++ uses streams for input/output.

  • C++ programs can also use C-style input/output, which don’t use streams.

  • Streams are objects that are defined to handle a device on which input or output operations are performed.

  • Streams allow C++ programs to interact with external entities controlled by the operating system,

    • such as:
      • program execution console
      • keyboard
      • files
  • Other external entities such as network sockets are not provided by basic C++ stream classes, but are available in various libraries (e.g. Boost).

2. cin/cout

  • I/O stream objects cin, cout, cerr

  • Defined in the C++ library called <iostream>

  • Must have these lines (pre-processor directives) :

    1
    2
    #include <iostream>
    using namespace std;
  • cout is an object that is an instance of the ostream class, defined in the iostream library.

  • cout is a stream, << is the stream insertion operator that is used to output to the stream.

  • Any data can be outputted to a stream

    • Variables
    • Constants
    • Literals (eg. string)
    • Results of expressions
  • Stream manipulators

    • set output specially-formatted numbers
      1
      2
      cout << fixed << showpoint << setprecision(2);
      //show exaclty 2 digits after the decimal point: 78.50
  • keyboard input stream

    • use cin for input from the keyboard
    • use >> (stram extraction operator)
    • cin >> num (right-hand-side must be a variable)

3. files stream declarations, open/close, usage

  • Similar to cin/cout streams, there are streams for input/output from/to files

    • File input : ifstream
    • File output : ofstream
    • Part of library <fstream>
    • use << operator to write
    • use >> operator to read
  • output:

    1
    2
    3
    4
    5
    6
    7
    //1
    ofstream outputfilestream;
    outputfilestream.open("scores.txt");
    //2
    ofstream outputfilestream("scores.txt");
    //
    outputfilestream.close();
  • input:

    1
    2
    3
    4
    5
    ifstream inputfilestream;
    infilestream.open("scores.txt");
    //or
    ifstream inputfilestream("scores.txt");
    inputfilestream.close();
  • fsteram object akso be used, but need to specify file modes, such as ios::out

    1
    2
    3
    4
    5
    6
    7
    8
    fstream filestream;
    filestream.open("scores.txt“, ios::out);
    //output operations
    filestream.close();
    //do other things
    filestream.open("scores.txt“, ios::in);
    //input operations
    filestream.close();
  • file modes:

    • ios::in Opens a file for input.
    • ios::out Opens a file for output.
    • ios::app Appends all output to the end of the file.
    • ios::ate Opens a file for output. If the file already exists, move to the end of the file. Data can be written anywhere in the file.
    • ios::trunc Discards the file’s contents if the file already exists. (This is the default action for ios:out).
    • ios::binary Opens a file for binary input and output.
  • some examples:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    ofstream output;
    // Create/open a file
    output.open("scores.txt");
    // Write two lines
    output << "John" << " " << "T" << " " << "Smith" << " " << 90 << endl;
    output << "Eric" << " " << "K" << " " << "Jones" << " " << 85 << endl;
    // Close the file
    output.close();
    //
    //
    ifstream input("scores.txt");
    string firstName, lastName; char mi; int score;
    input >> firstName >> mi >> lastName >> score;
    cout << firstName << " " << mi << " " << lastName << " " << score << endl;
    input >> firstName >> mi >> lastName >> score;
    cout << firstName << " " << mi << " " << lastName << " " << score << endl;
    input.close();

    //OR

    string firstName, lastName; char mi; int score;
    ifstream input("scores.txt");
    input >> firstName >> mi >> lastName >> score;
    while (!input.eof()) {
    cout << firstName << " " << mi << " " << lastName << " " << score << endl;
    input >> firstName >> mi >> lastName >> score;
    }
    input.close();
  • stream states and functions

    • eof() returns true if the eofbit flag is set.

    • fail() returns true if the failbit or hardfail flag is set

    • bad() returns true if the badbit flag is set

    • good() returns true is the goodbit flag is set

    • clear() clear all stream state flags

    • ios::eofbit set when the end of an input stream is reached

    • ios::failbit set when an operation on the stream has failed

    • ios::hardfail set when an unrecovered error has occurred

    • ios::badbit set when an invalid operation has been attempted

    • ios::goodbit set if none of the preceding bits is set

4. << and >> operator overloading

  • To enable a user-defined type to be outputted to a stream, the << operator must be overloaded to accept this type as an operand.

5. MFC serialization (NO)


Slide Set 4:

1. classes vs. structs

  • As classes are an expanded struct, it is also possible to declare and use a struct that includes member functions, and that even inherits from another struct, just like classes.

  • The only difference between class and struct is that the members of a struct are public by default, but private by default for a class.

  • A struct that does not use object-oriented features is nicknamed a POD for “plain old data structure”.

2. struct usage

  • Once the struct has been declared, it can be used as any other type

  • The members of a struct can be referred to using the dot notation

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct CDAccount1
    {
    double balance;
    double interestRate;
    int term;
    }

    int main()
    {
    CDAccount1 account;

    double interestRate;
    interestRate = account.interestRate/100.0;
    }

3. class declarations (.h and .cpp files)

  • A Class is an Abstract Data Type

  • A C++ class represents an abstract data type by allowing functions to be syntactically encapsulated into its definition, along with its data elements.

  • The syntax of a class definition is the same as for a struct.

4. declaring/using objects

  • Variables of a class type are referred to as objects.

  • Objects are declared using the same syntax as for basic types.

    1
    2
    DayOfYear today;
    DayOfYear *birthday = new DayOfYear();
  • Class types can be used anywhere a type can be used:

    • As type of a variable
    • As parameter to a function
    • As a return type to a function
    • As a value pointed to by a pointer
  • Members of a class are referred to using the dot notation and their access is regulated by the private, public and protected access specifiers.

* with or without pointers
  • The members of an object can be referred to using the dot notation:
    1
    2
    3
    int day1 = today.getDay();
    int day2 = *birthday.getDay(); // equivalent
    int day3 = birthday->getDay(); // equivalent
  • kinds of methods
    • Accessor: method whose goal is to expose a value in the state of an object, generally the value of a particular data member.
    • Mutator: method whose goal is to change a value in the state of an object.
    • Service method: method that exposes some service or desired behavior to other classes/objects.
    • Internal behavior methods: methods that are used by the class/object itself internally, that defines some of its behavior that should not be triggered explicitly from the exterior. These methods should thus be private.
    • Constructor: method whose goal is to manage the operations to be performed as an object is created.
    • Destructor: method whose goal is to manage the operations to be performed as an object is destroyed.

5. inline functions/methods

  • A function (or method) can be declared as inline, meaning that its entire code is to be replacing any call to this function.

  • Function inlining aims at execution optimization by eliminating the function call mechanism overhead.

  • However, it has the disadvantage of leading to code bloat if the body of the inline function contains a large amount of code and/or is consuming a large amount of memory and is called frequently at different places in the code.

  • To define a function as inline, one needs to include the inline keyword as a prefix to the function definition. The function declaration does not need to have the inline prefix.

  • In other words, inline functions have internal linkage. If you want to make an inline function accessible to other compilation units, they must include the definition of the inline function.

  • Note that declaring a function/method as inline is only a hint for the compiler, and that the compiler may choose not to inline a function if it is not possible, e.g. for recursive functions.

  • Rule of thumb: Inline your functions that have very short function definitions. Accessor methods are very good candidates for method inlining.

6. const specifier

  • Specifies that its subject is constant, i.e. that its value cannot be changed after it is set. Can be applied to:
    • Variables: A variable may be declared as const, which signifies that its value cannot be changed after it is initialized. It assumes that the variable is initialized upon declaration.
      1
      const DayOfYear newYearDay(1,1);
    • Function parameters: Declaring a function parameter as const means that the value of this parameter cannot be changed by the execution of
      1
      2
      3
      4
      int max(const int i1, const inbt i2)
      {
      return i1 >= i2 ? i1 : i2;
      }
    • Methods: Declaring a method as const means that this function will not alter the state of the object to which it belongs. By extension, only methods declared as const can be called on an object that was itself declared as const upon declaration.
      1
      2
      3
      4
      int DayOfYear::getDay() const
      {
      return day;
      }
  • Pointers involve two different concepts
    • the pointer itself
    • the value pointed to

7. static specifier

  • A member of a class can be declared as static, which means that this member is a class member, i.e. it belongs to the class as a whole an can be called on the class rather than on the objects.

  • If it is a data member, its value is unique across all objects of the class, i.e. it is a “class global variable”.

  • If a member function is declared as static, it can only use other members that are also declared as static.

  • Used to define state and behavior that is independent of any particular object’s state instantiated from this class.

  • Static member variables are generally initialized outside of the class declaration. Only constant static integral members can be initialized inside of the class declaration. The initialized value must be a constant expression.

  • Other languages allow static classes (e.g. C#), which C++ does not have.

  • Non-member variables can also be declared as static, which has a slightly
    different meaning:

    • When you declare a variable or function at file scope the static keyword specifies that the variable or function has internal linkage, i.e. it cannot be referred to outside of the compilation unit in which it is declared.
    • When you declare a local variable to a function as static, the variable has static duration, i.e. its value is kept even when the execution goes out of the scope of this function. In other words, it is a “global variable that has local scope to this function”.
  • All static variables persist from the start of the execution of the program until the program terminates.

  • Non-static member functions can access all data members of the class: static and non-static.

  • static member functions can only operate on the static data members, or call other static member functions.

8. friends

  • In principle, private and protected members of a class cannot be accessed from outside the class in which they are declared.

  • A friend (function or class) of a class may access the members designated as private or protected.

  • Friends are functions/methods or classes declared as such within a class.

  • Friends are not members, so they are not inherited from a superclass.

9. constructors/destructors

  • To sum-up, variables allocated on the stack are destroyed as we get out of the block’s scope, but objects allocated on the heap using new need to be manually destroyed using delete.

  • Rule of thumb: for every new, there should be a corresponding delete somewhere.

  • if you define your own constructor(s), make sure that you provide
    a default constructor, as the default constructor is likely to be called implicitly by the runtime system.

    * declaration/implementation
    * initialization list
    * implicit/explicit constructor calls
    * call chain
  • Destructors are called in the exact reverse order as the constructors.

10. inheritance

  • more flexible and extensible design

  • A base class is a class from which other classes inherit from.

    • Often called a super-class, or a parent or ancestor class.
  • A derived class is a class that inherits from a base class.

    • Often called a sub-class, or a child or descendent class.
    • Data Members
    • Member functions
    • not inherit
      • constructors, copy constructors
      • assignment operator
      • destructor
  • Multiple inheritance is when a derived class inherits from more than one base class.

  • An abstract class is a class that is meant to be derived from by containing abstract member functions that do not have a definition, assuming that they will find a concrete implementation in a derived class. Because of that, an abstract class cannot be instantiated.

overriding/overloading
  • Overriding is when a member function is included in a derived class, having exactly the same signature as an inherited member function.

  • A function’s signature is defined as:

    • Function’s name
    • Sequence of types in parameter list
    • Including order, number, and types of parameters
  • Signature does NOT include:

    • Return type
    • const keywords used for the function or the parameters
    • References specifiers (&) used for the parameters
  • Overloading is when two or more functions with the same name are
    defined in the same scope, each having different parameter lists.

  • Thus, overloading applies to inherited member functions, but also
    applies to free functions or operators available within a certain scope.

    vs. constructor/destructor implementation
    assignment operator
    copy constructor
    shallow/deep copy

11. multiple inheritance (Yes)

12. virtual inheritance (Yes)

13. diamond problem (Yes)


Slide Set 5:

1. statically allocated arrays (one(YES) / multidimensional(NO)

* declaration, usage
* memory allocation model
* passing as parameters

2. dynamically allocated arrays (one-dimensional (YES)) (multidimensional - NO)

* declaration, usage
* memory allocation model
* passing as parameters

3. array decay into a pointer(NO)

4. static array classes (NO)

5. STL containers (NO)

* declaration, usage (NO)
* iterators (NO)
Posted on

2020-10-24

Updated on

2021-01-31

Licensed under

Comments
Loading...Wait a Minute!