Appearance
面向对象
概述
面向对象编程(OOP)是C++的核心特性,包括封装、继承和多态三大特性。
类与对象
基本定义
cpp
#include <iostream>
#include <string>
using namespace std;
class Person {
public:
string name;
int age;
void introduce() {
cout << "我叫" << name << ",今年" << age << "岁。" << endl;
}
};
int main() {
Person p1;
p1.name = "张三";
p1.age = 25;
p1.introduce();
Person p2;
p2.name = "李四";
p2.age = 30;
p2.introduce();
return 0;
}构造函数
cpp
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
string name;
int age;
double score;
Student() {
name = "未知";
age = 0;
score = 0.0;
cout << "默认构造函数被调用" << endl;
}
Student(string n, int a, double s) {
name = n;
age = a;
score = s;
cout << "带参数构造函数被调用" << endl;
}
void display() {
cout << "姓名: " << name << ", 年龄: " << age
<< ", 成绩: " << score << endl;
}
};
int main() {
Student s1;
s1.display();
Student s2("张三", 20, 85.5);
s2.display();
Student s3 = Student("李四", 22, 90.0);
s3.display();
return 0;
}析构函数
cpp
#include <iostream>
#include <string>
using namespace std;
class Resource {
public:
string name;
Resource(string n) : name(n) {
cout << "构造: " << name << endl;
}
~Resource() {
cout << "析构: " << name << endl;
}
};
int main() {
cout << "程序开始" << endl;
{
Resource r1("资源1");
Resource r2("资源2");
}
cout << "程序结束" << endl;
return 0;
}成员初始化列表
cpp
#include <iostream>
#include <string>
using namespace std;
class Rectangle {
public:
const double width;
const double height;
double area;
Rectangle(double w, double h)
: width(w), height(h), area(w * h) {
cout << "矩形创建成功" << endl;
}
void display() {
cout << "宽: " << width << ", 高: " << height
<< ", 面积: " << area << endl;
}
};
int main() {
Rectangle rect(5.0, 3.0);
rect.display();
return 0;
}访问控制
public、private、protected
cpp
#include <iostream>
#include <string>
using namespace std;
class BankAccount {
private:
string accountNumber;
double balance;
protected:
string ownerName;
public:
BankAccount(string owner, string accNum, double initialBalance)
: ownerName(owner), accountNumber(accNum), balance(initialBalance) {}
void deposit(double amount) {
if (amount > 0) {
balance += amount;
cout << "存款成功: " << amount << endl;
}
}
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
cout << "取款成功: " << amount << endl;
} else {
cout << "取款失败: 余额不足或金额无效" << endl;
}
}
double getBalance() const {
return balance;
}
void displayInfo() {
cout << "户主: " << ownerName << endl;
cout << "账号: " << accountNumber << endl;
cout << "余额: " << balance << endl;
}
};
int main() {
BankAccount account("张三", "1234567890", 1000);
account.displayInfo();
account.deposit(500);
account.withdraw(200);
account.displayInfo();
return 0;
}拷贝控制
拷贝构造函数
cpp
#include <iostream>
#include <string>
using namespace std;
class StringWrapper {
public:
string *data;
StringWrapper(const string &s) {
data = new string(s);
cout << "构造: " << *data << endl;
}
StringWrapper(const StringWrapper &other) {
data = new string(*other.data);
cout << "拷贝构造: " << *data << endl;
}
~StringWrapper() {
cout << "析构: " << *data << endl;
delete data;
}
void display() {
cout << "内容: " << *data << endl;
}
};
int main() {
StringWrapper s1("Hello");
StringWrapper s2 = s1;
StringWrapper s3(s1);
s1.display();
s2.display();
s3.display();
return 0;
}拷贝赋值运算符
cpp
#include <iostream>
#include <string>
using namespace std;
class MyString {
public:
string *data;
MyString(const string &s = "") {
data = new string(s);
}
MyString(const MyString &other) {
data = new string(*other.data);
}
MyString& operator=(const MyString &other) {
if (this != &other) {
delete data;
data = new string(*other.data);
}
return *this;
}
~MyString() {
delete data;
}
void display() {
cout << *data << endl;
}
};
int main() {
MyString s1("Hello");
MyString s2("World");
cout << "赋值前:" << endl;
s1.display();
s2.display();
s2 = s1;
cout << "赋值后:" << endl;
s1.display();
s2.display();
return 0;
}静态成员
静态数据成员
cpp
#include <iostream>
using namespace std;
class Counter {
public:
static int count;
Counter() {
count++;
cout << "创建对象,当前数量: " << count << endl;
}
~Counter() {
count--;
cout << "销毁对象,当前数量: " << count << endl;
}
static int getCount() {
return count;
}
};
int Counter::count = 0;
int main() {
cout << "初始数量: " << Counter::getCount() << endl;
Counter c1;
Counter c2;
{
Counter c3;
}
cout << "最终数量: " << Counter::getCount() << endl;
return 0;
}友元
友元函数
cpp
#include <iostream>
using namespace std;
class Box {
private:
double width;
double height;
public:
Box(double w, double h) : width(w), height(h) {}
friend double getArea(const Box &box);
friend void displayBox(const Box &box);
};
double getArea(const Box &box) {
return box.width * box.height;
}
void displayBox(const Box &box) {
cout << "宽: " << box.width << ", 高: " << box.height << endl;
}
int main() {
Box box(5.0, 3.0);
displayBox(box);
cout << "面积: " << getArea(box) << endl;
return 0;
}友元类
cpp
#include <iostream>
using namespace std;
class Engine;
class Car {
private:
string brand;
int speed;
public:
Car(string b, int s) : brand(b), speed(s) {}
friend class Engine;
};
class Engine {
public:
void displayCarInfo(const Car &car) {
cout << "品牌: " << car.brand << ", 速度: " << car.speed << endl;
}
void accelerate(Car &car, int increment) {
car.speed += increment;
cout << "加速后速度: " << car.speed << endl;
}
};
int main() {
Car car("Toyota", 100);
Engine engine;
engine.displayCarInfo(car);
engine.accelerate(car, 20);
engine.displayCarInfo(car);
return 0;
}运算符重载
基本运算符
cpp
#include <iostream>
using namespace std;
class Complex {
public:
double real;
double imag;
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
Complex operator+(const Complex &other) const {
return Complex(real + other.real, imag + other.imag);
}
Complex operator-(const Complex &other) const {
return Complex(real - other.real, imag - other.imag);
}
Complex operator*(const Complex &other) const {
return Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real
);
}
bool operator==(const Complex &other) const {
return real == other.real && imag == other.imag;
}
friend ostream& operator<<(ostream &os, const Complex &c);
};
ostream& operator<<(ostream &os, const Complex &c) {
os << c.real;
if (c.imag >= 0) os << "+";
os << c.imag << "i";
return os;
}
int main() {
Complex c1(3, 4);
Complex c2(1, 2);
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
cout << "c1 + c2 = " << (c1 + c2) << endl;
cout << "c1 - c2 = " << (c1 - c2) << endl;
cout << "c1 * c2 = " << (c1 * c2) << endl;
cout << "c1 == c2: " << (c1 == c2 ? "true" : "false") << endl;
return 0;
}下标运算符
cpp
#include <iostream>
using namespace std;
class IntArray {
private:
int *data;
int size;
public:
IntArray(int s) : size(s) {
data = new int[size];
for (int i = 0; i < size; i++) {
data[i] = 0;
}
}
~IntArray() {
delete[] data;
}
int& operator[](int index) {
if (index < 0 || index >= size) {
throw out_of_range("索引越界");
}
return data[index];
}
const int& operator[](int index) const {
if (index < 0 || index >= size) {
throw out_of_range("索引越界");
}
return data[index];
}
int getSize() const { return size; }
};
int main() {
IntArray arr(5);
for (int i = 0; i < arr.getSize(); i++) {
arr[i] = i * 10;
}
for (int i = 0; i < arr.getSize(); i++) {
cout << "arr[" << i << "] = " << arr[i] << endl;
}
return 0;
}继承
基本继承
cpp
#include <iostream>
#include <string>
using namespace std;
class Animal {
protected:
string name;
public:
Animal(string n) : name(n) {}
void eat() {
cout << name << "正在吃东西" << endl;
}
void sleep() {
cout << name << "正在睡觉" << endl;
}
virtual void speak() {
cout << name << "发出声音" << endl;
}
};
class Dog : public Animal {
public:
Dog(string n) : Animal(n) {}
void speak() override {
cout << name << "汪汪叫" << endl;
}
void fetch() {
cout << name << "正在捡球" << endl;
}
};
class Cat : public Animal {
public:
Cat(string n) : Animal(n) {}
void speak() override {
cout << name << "喵喵叫" << endl;
}
void climb() {
cout << name << "正在爬树" << endl;
}
};
int main() {
Dog dog("旺财");
Cat cat("咪咪");
dog.eat();
dog.speak();
dog.fetch();
cout << "---" << endl;
cat.eat();
cat.speak();
cat.climb();
return 0;
}多重继承
cpp
#include <iostream>
#include <string>
using namespace std;
class Flyable {
public:
virtual void fly() {
cout << "正在飞行" << endl;
}
};
class Swimmable {
public:
virtual void swim() {
cout << "正在游泳" << endl;
}
};
class Duck : public Flyable, public Swimmable {
private:
string name;
public:
Duck(string n) : name(n) {}
void fly() override {
cout << name << "正在飞翔" << endl;
}
void swim() override {
cout << name << "正在游泳" << endl;
}
void quack() {
cout << name << "嘎嘎叫" << endl;
}
};
int main() {
Duck duck("唐老鸭");
duck.fly();
duck.swim();
duck.quack();
return 0;
}多态
虚函数
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Shape {
public:
virtual double area() = 0;
virtual double perimeter() = 0;
virtual void display() = 0;
virtual ~Shape() {}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() override {
return width * height;
}
double perimeter() override {
return 2 * (width + height);
}
void display() override {
cout << "矩形: 宽=" << width << ", 高=" << height << endl;
}
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() override {
return 3.14159 * radius * radius;
}
double perimeter() override {
return 2 * 3.14159 * radius;
}
void display() override {
cout << "圆形: 半径=" << radius << endl;
}
};
int main() {
vector<unique_ptr<Shape>> shapes;
shapes.push_back(make_unique<Rectangle>(5, 3));
shapes.push_back(make_unique<Circle>(4));
shapes.push_back(make_unique<Rectangle>(2, 6));
for (const auto &shape : shapes) {
shape->display();
cout << "面积: " << shape->area() << endl;
cout << "周长: " << shape->perimeter() << endl;
cout << "---" << endl;
}
return 0;
}纯虚函数与抽象类
cpp
#include <iostream>
#include <string>
using namespace std;
class Vehicle {
protected:
string brand;
int speed;
public:
Vehicle(string b, int s) : brand(b), speed(s) {}
virtual void start() = 0;
virtual void stop() = 0;
virtual void accelerate(int increment) = 0;
void displayInfo() {
cout << "品牌: " << brand << ", 速度: " << speed << endl;
}
virtual ~Vehicle() {}
};
class Car : public Vehicle {
public:
Car(string b, int s) : Vehicle(b, s) {}
void start() override {
cout << brand << "汽车启动" << endl;
}
void stop() override {
cout << brand << "汽车停止" << endl;
speed = 0;
}
void accelerate(int increment) override {
speed += increment;
cout << brand << "汽车加速到 " << speed << " km/h" << endl;
}
};
class Motorcycle : public Vehicle {
public:
Motorcycle(string b, int s) : Vehicle(b, s) {}
void start() override {
cout << brand << "摩托车启动" << endl;
}
void stop() override {
cout << brand << "摩托车停止" << endl;
speed = 0;
}
void accelerate(int increment) override {
speed += increment;
cout << brand << "摩托车加速到 " << speed << " km/h" << endl;
}
};
int main() {
Car car("Toyota", 0);
Motorcycle moto("Honda", 0);
car.start();
car.accelerate(50);
car.displayInfo();
car.stop();
cout << "---" << endl;
moto.start();
moto.accelerate(80);
moto.displayInfo();
moto.stop();
return 0;
}实践示例
图形绘制系统
cpp
#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
class Drawable {
public:
virtual void draw() const = 0;
virtual double getArea() const = 0;
virtual ~Drawable() = default;
};
class Point {
public:
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
class Shape : public Drawable {
protected:
Point position;
string color;
public:
Shape(Point p, string c) : position(p), color(c) {}
virtual void move(double dx, double dy) {
position.x += dx;
position.y += dy;
}
Point getPosition() const { return position; }
string getColor() const { return color; }
void setColor(const string &c) { color = c; }
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(Point p, double w, double h, string c)
: Shape(p, c), width(w), height(h) {}
void draw() const override {
cout << "绘制矩形: 位置(" << position.x << "," << position.y
<< "), 宽" << width << ", 高" << height
<< ", 颜色" << color << endl;
}
double getArea() const override {
return width * height;
}
double getWidth() const { return width; }
double getHeight() const { return height; }
};
class Circle : public Shape {
private:
double radius;
public:
Circle(Point p, double r, string c)
: Shape(p, c), radius(r) {}
void draw() const override {
cout << "绘制圆形: 圆心(" << position.x << "," << position.y
<< "), 半径" << radius
<< ", 颜色" << color << endl;
}
double getArea() const override {
return 3.14159 * radius * radius;
}
double getRadius() const { return radius; }
};
class Triangle : public Shape {
private:
double base, height;
public:
Triangle(Point p, double b, double h, string c)
: Shape(p, c), base(b), height(h) {}
void draw() const override {
cout << "绘制三角形: 位置(" << position.x << "," << position.y
<< "), 底边" << base << ", 高" << height
<< ", 颜色" << color << endl;
}
double getArea() const override {
return 0.5 * base * height;
}
};
class Canvas {
private:
vector<unique_ptr<Shape>> shapes;
public:
void addShape(unique_ptr<Shape> shape) {
shapes.push_back(move(shape));
}
void drawAll() const {
cout << "\n=== 画布内容 ===" << endl;
for (const auto &shape : shapes) {
shape->draw();
}
cout << "================\n" << endl;
}
double getTotalArea() const {
double total = 0;
for (const auto &shape : shapes) {
total += shape->getArea();
}
return total;
}
size_t getShapeCount() const {
return shapes.size();
}
};
int main() {
Canvas canvas;
canvas.addShape(make_unique<Rectangle>(Point(0, 0), 10, 5, "红色"));
canvas.addShape(make_unique<Circle>(Point(5, 5), 3, "蓝色"));
canvas.addShape(make_unique<Triangle>(Point(2, 3), 6, 4, "绿色"));
canvas.drawAll();
cout << "图形数量: " << canvas.getShapeCount() << endl;
cout << "总面积: " << canvas.getTotalArea() << endl;
return 0;
}小结
面向对象三大特性:
| 特性 | 说明 |
|---|---|
| 封装 | 隐藏实现细节,提供公共接口 |
| 继承 | 代码复用,建立类层次结构 |
| 多态 | 同一接口,不同实现 |
关键概念:
- 构造函数/析构函数:对象的创建与销毁
- 访问控制:public、private、protected
- 虚函数:实现运行时多态
- 纯虚函数:定义抽象类
- 运算符重载:自定义类型的运算行为