The Essence of Object-Oriented Programming
The core idea of Object-Oriented Programming (OOP) is to simulate concepts from the real world by creating custom data types, allowing data types to perfectly match the data being processed. This way of thinking makes the code more intuitive and easier to maintain.
C++ Built-in Basic Types
Integer Types
#include <iostream>
#include <climits> // View type limits
using namespace std;
int main() {
// Integer type example
short smallNumber = 100; // Short integer, usually 16 bits
int normalNumber = 100000; // Integer, usually 32 bits
long largeNumber = 1000000000L; // Long integer, usually 32 or 64 bits
long long hugeNumber = 1000000000000LL; // Long long integer, usually 64 bits
// View the range of each type
cout << "short range: " << SHRT_MIN << " to " << SHRT_MAX << endl;
cout << "int range: " << INT_MIN << " to " << INT_MAX << endl;
cout << "long range: " << LONG_MIN << " to " << LONG_MAX << endl;
// Signed and unsigned types
signed int negativeNumber = -100; // Signed integer (default)
unsigned int positiveOnly = 200; // Unsigned integer, can only store non-negative numbers
cout << "Signed integer: " << negativeNumber << endl;
cout << "Unsigned integer: " << positiveOnly << endl;
return 0;
}
Floating Point Types
#include <iostream>
#include <iomanip> // Control output format
#include <cmath> // Math functions
using namespace std;
int main() {
// Floating point type example
float simplePrecision = 3.14159f; // Single precision floating point
double normalPrecision = 3.1415926535; // Double precision floating point (default)
long double highPrecision = 3.141592653589793238L; // High precision floating point
// Set output precision
cout << fixed << setprecision(10);
cout << "float precision: " << simplePrecision << endl;
cout << "double precision: " << normalPrecision << endl;
cout << "long double precision: " << highPrecision << endl;
// Scientific notation
double largeNumber = 1.5e8; // 1.5 × 10^8
double smallNumber = 1.5e-8; // 1.5 × 10^-8
cout << scientific;
cout << "Large number in scientific notation: " << largeNumber << endl;
cout << "Small number in scientific notation: " << smallNumber << endl;
return 0;
}
Variables and Basic Operations
#include <iostream>
using namespace std;
int main() {
// Variable declaration and initialization
int age = 25; // Declare and initialize
double salary; // Declaration
salary = 50000.50; // Subsequent assignment
const double PI = 3.14159; // Constant, cannot be modified
// Arithmetic operations
int a = 10, b = 3;
cout << "a = " << a << ", b = " << b << endl;
cout << "Addition: " << a + b << endl;
cout << "Subtraction: " << a - b << endl;
cout << "Multiplication: " << a * b << endl;
cout << "Division: " << a / b << endl; // Integer division
cout << "Modulus: " << a % b << endl;
// Floating point operations
double x = 10.0, y = 3.0;
cout << "Floating point division: " << x / y << endl;
// Compound assignment operators
int count = 5;
count += 3; // Equivalent to count = count + 3
cout << "After count += 3: " << count << endl;
// Increment and decrement
int number = 5;
cout << "Original value: " << number << endl;
cout << "Post-increment: " << number++ << endl; // Use first, then increase
cout << "Current value: " << number << endl;
cout << "Pre-increment: " << ++number << endl; // Increase first, then use
return 0;
}
Type Conversion
#include <iostream>
using namespace std;
int main() {
// Implicit type conversion
int integer = 10;
double decimal = 3.14;
double result1 = integer + decimal; // int automatically converted to double
cout << "int + double = " << result1 << endl;
// Explicit type conversion (C-style)
double pi = 3.14159;
int intPi = (int)pi; // Force conversion to int, losing the decimal part
cout << "double 3.14159 converted to int: " << intPi << endl;
// C++ style type conversion
double price = 19.99;
int intPrice = static_cast<int>(price); // Static type conversion
cout << "static_cast<int>(19.99) = " << intPrice << endl;
// Conversion between characters and integers
char letter = 'A';
int asciiValue = static_cast<int>(letter);
cout << "ASCII value of 'A': " << asciiValue << endl;
int number = 66;
char character = static_cast<char>(number);
cout << "Character corresponding to ASCII 66: " << character << endl;
return 0;
}
Designing Custom Data Types
Now let’s see how to create our own data types based on these basic types:
#include <iostream>
#include <string>
using namespace std;
// Custom data type: Bank Account
class BankAccount {
private:
string accountNumber; // Account number
string ownerName; // Account holder
double balance; // Balance
public:
// Constructor
BankAccount(const string& accNum, const string& name, double initialBalance) {
accountNumber = accNum;
ownerName = name;
balance = initialBalance;
}
// Deposit method
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "Successfully deposited: $" << amount << endl;
} else {
cout << "Deposit amount must be greater than 0" << endl;
}
}
// Withdraw method
bool withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
cout << "Successfully withdrew: $" << amount << endl;
return true;
} else {
cout << "Withdrawal failed: Insufficient balance or invalid amount" << endl;
return false;
}
}
// Display account information
void displayInfo() const {
cout << "Account number: " << accountNumber << endl;
cout << "Account holder: " << ownerName << endl;
cout << "Current balance: $" << balance << endl;
}
// Get balance
double getBalance() const {
return balance;
}
};
int main() {
// Using custom data type
BankAccount myAccount("123456789", "Zhang San", 1000.0);
cout << "=== Initial Account Information ===" << endl;
myAccount.displayInfo();
cout << "\n=== Performing Transactions ===" << endl;
myAccount.deposit(500.0);
myAccount.withdraw(200.0);
myAccount.withdraw(2000.0); // This will fail
cout << "\n=== Final Account Information ===" << endl;
myAccount.displayInfo();
return 0;
}
More Complex Custom Type Example
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Custom data type: Student Grade Management System
class Student {
private:
string name;
int id;
vector<double> grades; // Using composite type to store list of grades
public:
Student(const string& studentName, int studentId)
: name(studentName), id(studentId) {}
// Add grade
void addGrade(double grade) {
if (grade >= 0 && grade <= 100) {
grades.push_back(grade);
cout << "Added grade for " << name << ": " << grade << endl;
} else {
cout << "Invalid grade: " << grade << " (Grade should be between 0-100)" << endl;
}
}
// Calculate average
double calculateAverage() const {
if (grades.empty()) {
return 0.0;
}
double sum = 0.0;
for (double grade : grades) {
sum += grade;
}
return sum / grades.size();
}
// Display student information
void displayInfo() const {
cout << "Student ID: " << id << endl;
cout << "Name: " << name << endl;
cout << "Grades: ";
for (double grade : grades) {
cout << grade << " ";
}
cout << endl;
cout << "Average: " << calculateAverage() << endl;
}
};
int main() {
// Create student objects
Student student1("Li Si", 1001);
Student student2("Wang Wu", 1002);
// Add grades
student1.addGrade(85.5);
student1.addGrade(92.0);
student1.addGrade(78.5);
student2.addGrade(90.0);
student2.addGrade(88.5);
student2.addGrade(95.0);
// Display information
cout << "=== Student Information ===" << endl;
student1.displayInfo();
cout << endl;
student2.displayInfo();
return 0;
}
Key Points Summary
- Understanding Basic Types: Integer and floating-point types are the foundation for building more complex types
- Type Matching: Choosing the right data type can make the code more efficient and safer
- Type Conversion: Understanding the rules and risks of implicit and explicit type conversion
- Custom Types: Encapsulating data and operations together using classes
- Data Abstraction: Hiding implementation details while exposing necessary interfaces
By correctly designing your own data types, you can create code that is easier to understand and maintain, which is the core value of object-oriented programming.