mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-19 10:54:06 -06:00
pushing changes for cpp
This commit is contained in:
parent
c17185aca5
commit
3281c61e21
@ -0,0 +1 @@
|
||||
Physiological Psychology is the study of the nervous system, and how it relates to mind/cognition, behaviour, and the rest of the peripheral body.
|
||||
@ -0,0 +1,13 @@
|
||||
## Early Greeks
|
||||
|
||||
**Encephalocentric Theory:** Posited that the brain, not the heart, was the center of human consciousness, intelligence, sensation, and emotions.
|
||||
- **Claimed by Hippocrates** who lived from 460BCE to 379BCE
|
||||
**Cardiocentric Theory:** Posited that the heart was the center of human consciousness, intelligence, and emotion.
|
||||
- **Claimed by Aristotle** who lived from 384 BCE to 322 BCE
|
||||
**Dualism:** suggests that mind and body are separate
|
||||
- **Claimed by Plato** who lived from 428BCE to 348BCE
|
||||
**Monism:** suggests that mind and body are one.
|
||||
- **Claimed by Epicurus** who lived from 341 BCE to 270 BCE
|
||||
|
||||
## Rene Descartes (1596 - 1650)
|
||||
Pushed the idea of mind-body **dualism** (**Cartesian Dualism**)
|
||||
4
content/Roboting/C++ "Knobs"/C++ "Knobs".md
Normal file
4
content/Roboting/C++ "Knobs"/C++ "Knobs".md
Normal file
@ -0,0 +1,4 @@
|
||||
#cpp #objectOrientedProgramming #polymorphism
|
||||
|
||||
Cheatsheet of various "knobs" used to design class interactions in C++. I'm mainly talking about key C++ specifiers and concepts that always tend to fly over my head.
|
||||
|
||||
73
content/Roboting/C++ "Knobs"/Encapsulation Knobs.md
Normal file
73
content/Roboting/C++ "Knobs"/Encapsulation Knobs.md
Normal file
@ -0,0 +1,73 @@
|
||||
#cpp #objectOrientedProgramming
|
||||
|
||||
These refer to specifiers and keywords that control what you hide or expose details to downstream objects.
|
||||
|
||||
**Access specifiers:** Define what class methods / members are accessible externally.
|
||||
- `public`: accessible externally
|
||||
- `private`: only accessible internally, *also with `friends`*
|
||||
- `protected`: only accessible internally and to classes that inherit the class, *also with `friends`*
|
||||
|
||||
**Getters and Setters:** Exposes read and write functionality to private members through a public interface (that is, a public class method).
|
||||
|
||||
**Friend classes and functions:** `friend` specifier gives special access to private / protected members and methods. breaking encapsulation.
|
||||
|
||||
**Namespaces:** `namespace` specifier controls visibility of code to others. Code within the same namespace can see each other, while code outside of the namespace has to specify the namespace to properly interface with it.
|
||||
### Code Implementation
|
||||
|
||||
```c++
|
||||
namespace wato::power_management {
|
||||
|
||||
class Battery {
|
||||
public:
|
||||
double get_percent() {
|
||||
return percent_;
|
||||
}
|
||||
private:
|
||||
double percent_ = 100;
|
||||
|
||||
friend class BatteryTesterFriend; // BatteryTesterFriend can see private stuff
|
||||
friend std::ostream& operator<<(std::ostream& os, const Battery& B);
|
||||
};
|
||||
|
||||
class BatteryTesterNotFriend {
|
||||
public:
|
||||
bool track_percent(Battery& B) { // this will pass because we are using Battery's public interface
|
||||
tracked_percentage_ = B.get_percent();
|
||||
return true;
|
||||
}
|
||||
bool drain(Battery& B) { // this will fail because this class is not a friend of Battery, and thus cannot directly set percent_
|
||||
B.percent_ = 0;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
double tracked_percentage_;
|
||||
};
|
||||
|
||||
class BatteryTesterFriend {
|
||||
public:
|
||||
bool track_percent(Battery& B) { // this will pass because we are using Battery's public interface
|
||||
tracked_percentage_ = B.get_percent();
|
||||
return true;
|
||||
}
|
||||
bool drain(Battery& B) { // this will pass because this class IS a friend of Battery, and thus can directly mutate percent_
|
||||
B.percent_ = 0;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
double tracked_percentage_;
|
||||
};
|
||||
|
||||
// friend function to print the battery percentage
|
||||
std::ostream& operator<<(std::ostream& os, const Battery& B) {
|
||||
os << "Battery.percent_" << B.percent_;
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace wato::power_management
|
||||
|
||||
int main() {
|
||||
wato::power_management::Battery test_battery();
|
||||
std::cout << test_battery << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
142
content/Roboting/C++ "Knobs"/Inheritance Knobs.md
Normal file
142
content/Roboting/C++ "Knobs"/Inheritance Knobs.md
Normal file
@ -0,0 +1,142 @@
|
||||
#cpp #objectOrientedProgramming #polymorphism
|
||||
|
||||
These refer to specifiers and concepts related to inheritance and how classes can "reuse" or "extend" the functionality from other classes.
|
||||
|
||||
**Public/Private/Protected Inheritance:** `public` will keep parent methods / members public when public, protected when protected, private when private. `protected` inheritance will make public things protected. `private` inheritance will make public and protected things private.
|
||||
|
||||
**Multiple Inheritance:** you can compose and share the functionality from multiple bases. You can over overwrite virtual functions from both.
|
||||
|
||||
**Final/Override:** `virtual` methods and constructors can be overridden. If an implementation states the overridden method as `final` then no downstream class can override it.
|
||||
|
||||
[!tip] If `virtual` is left out, then you lose runtime polymorphism and will resort to the base implementation
|
||||
|
||||
### Code Implementation
|
||||
```c++
|
||||
// ############## private, public, protected inheritance and virtuals and overrides ##############
|
||||
class Base {
|
||||
public:
|
||||
void say_public() {
|
||||
std::cout << "A\n";
|
||||
}
|
||||
|
||||
// polymorphic surface
|
||||
// const here means "this function promises to not modify the object's state (except for members marked as mutable)"
|
||||
virtual void overwrite_me() const {
|
||||
std::cout << "I am virtual and I can be overridden.\n";
|
||||
}
|
||||
protected:
|
||||
void say_protected() {
|
||||
std::cout << "B\n";
|
||||
}
|
||||
private:
|
||||
void say_private() {
|
||||
std::cout << "C\n";
|
||||
}
|
||||
};
|
||||
|
||||
// public inheritance, base's public stays public, protected stays protected, private in unaccesible
|
||||
class PubChild : public Base {
|
||||
public:
|
||||
void call_base() {
|
||||
say_public(); // will work, public interface
|
||||
say_protected(); // will work, inherits so protected will be accessible
|
||||
say_private(); // will NOT work, private and unaccessible within Base
|
||||
}
|
||||
};
|
||||
|
||||
// protected inheritance, base's public AND protected will be become protected to outsiders
|
||||
class ProtChild : protected Base {
|
||||
public:
|
||||
using Base::say_public; // this will re-expose the public-turned-protected method back as a public
|
||||
|
||||
void call_base() {
|
||||
say_public(); // will work, public interface
|
||||
say_protected(); // will work, inherits so protected will be accessible
|
||||
say_private(); // will NOT work, private and unaccessible within Base
|
||||
}
|
||||
};
|
||||
|
||||
// private inheritance, base's public and protected will become private to outsiders
|
||||
class PrivChild : private Base {
|
||||
public:
|
||||
using Base::say_public; // this will re-expose the public-turned-private method back to public
|
||||
|
||||
void call_base() {
|
||||
say_public(); // will work, public interface
|
||||
say_protected(); // will work, inherits so protected will be accessible
|
||||
say_private(); // will NOT work, private and unaccessible within Base
|
||||
}
|
||||
};
|
||||
|
||||
// overridding virtual method
|
||||
class OverridingChild: public Base {
|
||||
public:
|
||||
// the final modifier here means that no further child can override this function, will error out otherwise
|
||||
virtual void const override override_me() final {
|
||||
std::cout << "I have been overridden\n";
|
||||
}
|
||||
};
|
||||
|
||||
// this downstream class will fail to override the virtual method because its final override happenned in OverridingChild
|
||||
class AnotherOverridingChild: public OverridingChild {
|
||||
public:
|
||||
virtual void const override override_me() {
|
||||
std::cout << "I am trying to override\n";
|
||||
}
|
||||
};
|
||||
|
||||
// ############## multiple inheritance ##############
|
||||
class ElectricalButton {
|
||||
public:
|
||||
virtual void push_button() {
|
||||
std::cout << "I am pressed the button and it does nothing.\n";
|
||||
}
|
||||
};
|
||||
|
||||
class ElectricalLever {
|
||||
public:
|
||||
virtual void flip_lever() {
|
||||
std::cout << "I am flipped the lever and it does nothing.\n";
|
||||
}
|
||||
};
|
||||
|
||||
class LightFixture : public ElectricalButton, public ElectricalLever {
|
||||
public:
|
||||
virtual void override push_button() {
|
||||
std::cout << "I pushed the button and the light turned on.\n";
|
||||
}
|
||||
|
||||
virtual void override flip_lever() {
|
||||
std::cout << "I flipped the lever and the light turned on.\n";
|
||||
}
|
||||
};
|
||||
|
||||
// ############## Diamond Problem ##############
|
||||
class RobotBase {
|
||||
public:
|
||||
RobotBase(int length, int width) {
|
||||
length_ = length;
|
||||
width_ = width;
|
||||
}
|
||||
private:
|
||||
int length_;
|
||||
int width_;
|
||||
};
|
||||
|
||||
class TinyRobot : private RobotBase {
|
||||
public:
|
||||
virtual TinyRobot() : RobotBase(0, 0) {}
|
||||
};
|
||||
|
||||
class BigRobot : private RobotBase {
|
||||
public:
|
||||
virtual BigRobot() : RobotBase(0, 0) {}
|
||||
};
|
||||
|
||||
// Issue is that both TinyRobot and BigRobot inherit from RobotBase, so in order to stop Swarm from initializing two RobotBase, making things ambiguous, we can use virtual specifier to make the most derived class be responsible for constructing the virtual base RobotBase.
|
||||
class Swarm : public TinyRobot, public BigRobot {
|
||||
public:
|
||||
Swarm(int length, int width)
|
||||
: RobotBase(length, width), TinyRobot(), BigRobot() {}
|
||||
};
|
||||
```
|
||||
3
content/Roboting/C++ "Knobs"/Polymorphism Knobs.md
Normal file
3
content/Roboting/C++ "Knobs"/Polymorphism Knobs.md
Normal file
@ -0,0 +1,3 @@
|
||||
#cpp #objectOrientedProgramming #polymorphism
|
||||
|
||||
These refer to specifiers and concepts that control polymorphism.
|
||||
112
content/Roboting/Polymorphism.md
Normal file
112
content/Roboting/Polymorphism.md
Normal file
@ -0,0 +1,112 @@
|
||||
#polymorphism
|
||||
|
||||
Means "many forms", and refers to how a single interface can have many different implementations and handle different underlying types.
|
||||
|
||||
## Compile-time Polymorphism (or Static Polymorphism)
|
||||
|
||||
Polymorphism that occurs during compile time. The right implementation is chosen by the passed in arguments.
|
||||
|
||||
### Function Overloading
|
||||
|
||||
Functions can have different implementations based on different arguments. The compiler chooses the right function by matching the usage of the function and its arguments with the right overloaded function.
|
||||
|
||||
```c++
|
||||
class OverloadedClass {
|
||||
public:
|
||||
void print(int A) {
|
||||
std::cout << A << std::endl;
|
||||
}
|
||||
void print(double B) {
|
||||
std::cout << B << std::endl;
|
||||
}
|
||||
void print(std::string S) {
|
||||
std::cout << S << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
OverloadedClass overload_class();
|
||||
|
||||
double print_this = 100;
|
||||
overload_class.print(print_this); // compiler will choose void print(double B); at compile-time
|
||||
}
|
||||
```
|
||||
|
||||
### Operator Overloading
|
||||
|
||||
Similar to function overloading, just with operators.
|
||||
|
||||
```c++
|
||||
class OverloadedOperatorClass {
|
||||
public:
|
||||
OverloadedOperatorClass(int x, int y) : x_(x), y_(y) {}
|
||||
|
||||
int get_x() const { return x_; }
|
||||
int get_y() const { return y_; }
|
||||
|
||||
OverloadedOperatorClass operator+(const OverloadedOperatorClass& other) {
|
||||
return OverloadedOperatorClass(x_ + other.get_x(), y_ + other.get_y());
|
||||
}
|
||||
|
||||
OverloadedOperatorClass operator-(const OverloadedOperatorClass& other) {
|
||||
return OverloadedOperatorClass(x_ - other.get_x(), y_ - other.get_y());
|
||||
}
|
||||
|
||||
private:
|
||||
int x_;
|
||||
int y_;
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
## Runtime Polymorphism (or Dynamic Polymorphism)
|
||||
|
||||
Polymorphism that occurs during runtime. This is done with virtual functions and inheritance. Usually a base class provides some initial interface to override (via virtual methods). **Calls are resolved at runtime using a Virtual Table (vtable) mechanism.**
|
||||
|
||||
### Virtual Methods
|
||||
|
||||
When a method in a class is set as `virtual`, other classes that inherit it will be able to override the method using the `override` specifier. They can also make they override the be-all-end-all override by specifying `final`
|
||||
|
||||
```c++
|
||||
class BaseShape {
|
||||
public:
|
||||
virtual void draw_shape() { std::cout << "drawing shape\n"; }
|
||||
virtual ~BaseShape() = default; // why?
|
||||
};
|
||||
|
||||
class Square : public BaseShape {
|
||||
public:
|
||||
void override draw_shape() final { std::cout << "drawing square\n"; }
|
||||
};
|
||||
|
||||
class Circle : public BaseShape {
|
||||
public:
|
||||
void override draw_shape() final { std::cout << "drawing circle\n"; }
|
||||
};
|
||||
|
||||
class Squares : public Square {
|
||||
public:
|
||||
void override draw_shape() { std::cout << "drawing circle\n"; } // NOT POSSIBLE, because we indicated final on the virtual function override in Square
|
||||
};
|
||||
```
|
||||
|
||||
### Virtual Destructor
|
||||
|
||||
Virtual destructors can be useful for avoiding memory leaks. This is especially important when you are only deleting the base object of a derived class, forgetting to also delete the derived class itself.
|
||||
|
||||
```c++
|
||||
class BaseShape {
|
||||
public:
|
||||
virtual void draw_shape() { std::cout << "drawing shape\n"; }
|
||||
~BaseShape() = default; // <-- here I am telling the compiler to use its standard implementation of this destructor function (not virtual)
|
||||
};
|
||||
|
||||
class Star {
|
||||
public:
|
||||
virtual void draw_shape() { std::cout << "drawing star\n" << star_shape << std::endl; }
|
||||
~Star() = default;
|
||||
private:
|
||||
std::string star_shape = "_/\_\n";
|
||||
};
|
||||
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user