Video
Struct vs Class
- struct is default public
- class is default private
What is a C++ struct?
Level up your coding skills. No more passive learning. Interactive in-browser environments keep you engaged and test your progress as you go.
👌 C++ struct, short for C++ Structure, is a user-defined data type available in C++. It allows users to combine data items of (possibly) different data types under a single name.
Run in Repl.it https://repl.it/join/qhyexqcp-maikolguzman
C++
#include <iostream> // allows program to output data to the screen
struct Base {
public:
int numA = 0;
protected:
int numB = 1;
protected:
int numC = 2;
};
struct Derived: public Base {
Derived() {
numA = 3;
}
public:
int numD = 3;
protected:
int numE = 4;
private:
int numF = 5;
};
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA!" << std::endl; // display message
Derived derived;
derived.numA = 100;
return 0; // indicate that program ended successfully
} // end function main
Virtual Functions
📌 We can create programs with different behaviors in runtime, taking advantage of runtime polymorphism.
virtual
is used to create methods that are chosen at runtime- When a method is declared
virtual
, the most derived version of that method is executed at runtime - Extra time cost for the CPU
- If a member of a derived class matches the signature of the member in a base class, the derived method is automatically
virtual
.
Run in Repl.it https://repl.it/@MaikolGuzman/virtual-01-basic
C++
#include <iostream> // allows program to output data to the screen
struct Base {
virtual int get() const {
return 4;
}
/*int get() const {
return 4;
}*/
};
struct Derived : Base {
int get() const {
return 1;
}
};
int get(const Base &b) {
return b.get();
}
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA! (VIRTUAL)" << std::endl; // display message
Derived derived;
return get(derived);
} // end function main
Pure virtual functions
Functions declared with this signature are called “Pure Virtual”.
C++
virtual int get() const = 0;
Virtual Destructors
- Destructors can be declared
virtual
- Like regular member functions,
virtual
destructors ensure that the most derived version is called - Also, like regular member functions,
virtual
destructors only come in to play if you access an object via a pointer to a base class (example deleting it) - If a base class destructor is
virtual
, so is the automatically created derived class destructor
Run in Repl.it https://repl.it/@MaikolGuzman/virtual-03-destructors
C++
#include <iostream> // allows program to output data to the screen
struct Base {
virtual ~Base() {
std::cout << "~Base()\n";
}
/*~Base() {
std::cout << "~Base()\n";
}*/
};
struct Derived : Base {
~Derived() {
std::cout << "~Derived()\n";
}
};
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA! (VIRTUAL)" << std::endl;
Base *base = new Derived();
delete base; // what is printed here?
} // end function main
Abstract Classes
- Any class with unimplemented pure virtual functions is an “abstract class”
- Abstract classes cannot be initialized.
Run in Repl.it https://repl.it/@MaikolGuzman/virtual-02-abstract-class
C++
#include <iostream> // allows program to output data to the screen
struct Base {
virtual void doSomething() = 0;
};
struct Derived : Base {
void doSomething() {
}
};
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA! (VIRTUAL)" << std::endl;
Derived derived;
} // end function main
Override
- override tells the compiler that you are intending to change the behavior of a method in a base class
- If a function marked as override does not properly override an existing virtual function in a base class, a compile-time error is thrown.
Run in Repl.it https://repl.it/@MaikolGuzman/override-01-base
C++
#include <iostream> // allows program to output data to the screen
struct Base {
virtual void doSomething() const {
}
};
struct Derived : Base {
void doSomething() const override {
std::cout << "Hola Mike!!!" << std::endl;
}
};
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA! (VIRTUAL)" << std::endl;
Derived derived;
derived.doSomething();
} // end function main
Final
final
can be applied to either methods or classes.- A class marked final cannot be further inherited from.
- A method marked final cannot be further overridden.
- If a function marked as final does not properly override an existing virtual function, a compile-time error is thrown.
Run in Repl.it https://repl.it/@MaikolGuzman/override-02-final
C++
#include <iostream> // allows program to output data to the screen
struct Base {
virtual void doSomething() const {
}
};
struct Intermediate : Base {
void doSomething() const final {
std::cout << "Hola Intermedio!!!" << std::endl;
}
};
struct Derived : Intermediate {
/*void doSomething() const override {
std::cout << "Hola Mike!!!" << std::endl;
}*/
};
// function main begins program execution
int main(int argc, const char *argv[]) {
std::cout << "Welcome to the UNA! (VIRTUAL)" << std::endl;
Derived derived;
derived.doSomething();
} // end function main
📌 Best Practices
- Only define a destructor if you must
- Always define a virtual destructor if you have a virtual function (the compiler will warn you).