Appearance
面向对象进阶
本章将深入探讨C++面向对象编程的高级特性,包括继承、多态、虚函数、抽象类等概念。
继承
基本继承
cpp
#include <iostream>
#include <string>
using namespace std;
// 基类(父类)
class Animal {
protected: // 保护成员,派生类可以访问
string name;
int age;
public:
Animal(string n = "", int a = 0) : name(n), age(a) {
cout << "Animal构造函数" << endl;
}
virtual ~Animal() { // 虚析构函数
cout << "Animal析构函数" << endl;
}
void eat() {
cout << name << "正在吃东西" << endl;
}
void sleep() {
cout << name << "正在睡觉" << endl;
}
virtual void speak() { // 虚函数
cout << name << "发出声音" << endl;
}
void display() {
cout << "姓名: " << name << ", 年龄: " << age << endl;
}
};
// 派生类(子类)
// class 派生类 : 继承方式 基类
class Dog : public Animal {
private:
string breed; // 品种
public:
Dog(string n, int a, string b) : Animal(n, a), breed(b) {
cout << "Dog构造函数" << endl;
}
~Dog() {
cout << "Dog析构函数" << endl;
}
// 新增成员函数
void fetch() {
cout << name << "正在捡球" << endl;
}
// 重写基类虚函数
void speak() override { // override关键字(C++11)
cout << name << "汪汪叫!" << endl;
}
void displayBreed() {
cout << "品种: " << breed << endl;
}
};
// 另一个派生类
class Cat : public Animal {
private:
string color;
public:
Cat(string n, int a, string c) : Animal(n, a), color(c) {
cout << "Cat构造函数" << endl;
}
~Cat() {
cout << "Cat析构函数" << endl;
}
void climb() {
cout << name << "正在爬树" << endl;
}
void speak() override {
cout << name << "喵喵叫!" << endl;
}
};
int main() {
cout << "===== Dog对象 =====" << endl;
Dog dog("旺财", 3, "金毛");
dog.display(); // 继承自Animal
dog.eat(); // 继承自Animal
dog.speak(); // 重写的版本
dog.fetch(); // Dog特有
dog.displayBreed();
cout << "\n===== Cat对象 =====" << endl;
Cat cat("咪咪", 2, "橘色");
cat.display();
cat.sleep();
cat.speak();
cat.climb();
return 0;
}继承方式
cpp
#include <iostream>
using namespace std;
class Base {
public:
int publicVar;
protected:
int protectedVar;
private:
int privateVar;
public:
Base() : publicVar(1), protectedVar(2), privateVar(3) {}
};
// 公有继承
class PublicDerived : public Base {
public:
void access() {
publicVar = 10; // 可以访问,仍为public
protectedVar = 20; // 可以访问,仍为protected
// privateVar = 30; // 不能访问
}
};
// 保护继承
class ProtectedDerived : protected Base {
public:
void access() {
publicVar = 10; // 可以访问,变为protected
protectedVar = 20; // 可以访问,仍为protected
// privateVar = 30; // 不能访问
}
};
// 私有继承
class PrivateDerived : private Base {
public:
void access() {
publicVar = 10; // 可以访问,变为private
protectedVar = 20; // 可以访问,变为private
// privateVar = 30; // 不能访问
}
};
int main() {
PublicDerived pub;
pub.publicVar = 100; // 可以访问
ProtectedDerived pro;
// pro.publicVar = 100; // 不能访问,已变为protected
PrivateDerived pri;
// pri.publicVar = 100; // 不能访问,已变为private
/*
* 继承方式对成员访问权限的影响:
*
* 基类成员 公有继承 保护继承 私有继承
* public public protected private
* protected protected protected private
* private 不可访问 不可访问 不可访问
*/
return 0;
}多态
虚函数与多态
cpp
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
// 抽象基类
class Shape {
protected:
string name;
public:
Shape(string n) : name(n) {}
// 纯虚函数:使类成为抽象类
virtual double area() const = 0;
virtual double perimeter() const = 0;
// 虚函数
virtual void display() const {
cout << "形状: " << name << endl;
}
// 虚析构函数
virtual ~Shape() {
cout << "Shape析构" << endl;
}
};
// 具体类:圆形
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : Shape("圆形"), radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
double perimeter() const override {
return 2 * 3.14159 * radius;
}
void display() const override {
Shape::display(); // 调用基类版本
cout << "半径: " << radius << endl;
cout << "面积: " << area() << endl;
cout << "周长: " << perimeter() << endl;
}
~Circle() {
cout << "Circle析构" << endl;
}
};
// 具体类:矩形
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : Shape("矩形"), width(w), height(h) {}
double area() const override {
return width * height;
}
double perimeter() const override {
return 2 * (width + height);
}
void display() const override {
Shape::display();
cout << "宽: " << width << ", 高: " << height << endl;
cout << "面积: " << area() << endl;
cout << "周长: " << perimeter() << endl;
}
~Rectangle() {
cout << "Rectangle析构" << endl;
}
};
// 具体类:三角形
class Triangle : public Shape {
private:
double a, b, c; // 三边长度
public:
Triangle(double a, double b, double c)
: Shape("三角形"), a(a), b(b), c(c) {}
double area() const override {
// 海伦公式
double s = (a + b + c) / 2;
return sqrt(s * (s - a) * (s - b) * (s - c));
}
double perimeter() const override {
return a + b + c;
}
void display() const override {
Shape::display();
cout << "边长: " << a << ", " << b << ", " << c << endl;
cout << "面积: " << area() << endl;
cout << "周长: " << perimeter() << endl;
}
};
int main() {
// 使用基类指针实现多态
vector<unique_ptr<Shape>> shapes;
shapes.push_back(make_unique<Circle>(5.0));
shapes.push_back(make_unique<Rectangle>(4.0, 6.0));
shapes.push_back(make_unique<Triangle>(3.0, 4.0, 5.0));
cout << "===== 多态演示 =====" << endl;
for (const auto& shape : shapes) {
shape->display(); // 调用各自的display
cout << endl;
}
// 计算总面积
double totalArea = 0;
for (const auto& shape : shapes) {
totalArea += shape->area(); // 多态调用
}
cout << "总面积: " << totalArea << endl;
return 0;
}虚函数表
cpp
#include <iostream>
using namespace std;
class Base {
public:
virtual void func1() { cout << "Base::func1" << endl; }
virtual void func2() { cout << "Base::func2" << endl; }
void normalFunc() { cout << "Base::normalFunc" << endl; }
};
class Derived : public Base {
public:
void func1() override { cout << "Derived::func1" << endl; }
void func2() override { cout << "Derived::func2" << endl; }
void normalFunc() { cout << "Derived::normalFunc" << endl; }
};
int main() {
/*
* 虚函数表(vtable):
*
* 1. 每个包含虚函数的类都有一个虚函数表
* 2. 虚函数表是一个函数指针数组
* 3. 每个对象包含一个指向虚函数表的指针(vptr)
* 4. 运行时通过vptr找到vtable,实现动态绑定
*/
Base* ptr;
Derived d;
ptr = &d;
// 虚函数:动态绑定(运行时决定)
ptr->func1(); // Derived::func1
ptr->func2(); // Derived::func2
// 非虚函数:静态绑定(编译时决定)
ptr->normalFunc(); // Base::normalFunc
// 直接调用Derived的方法
d.normalFunc(); // Derived::normalFunc
return 0;
}抽象类与接口
cpp
#include <iostream>
#include <string>
using namespace std;
// 抽象类:包含纯虚函数
class Drawable {
public:
// 纯虚函数
virtual void draw() const = 0;
virtual void resize(double factor) = 0;
// 虚析构函数
virtual ~Drawable() = default;
// 可以有普通成员函数
void showInfo() {
cout << "这是一个可绘制对象" << endl;
}
};
// 接口:只有纯虚函数的抽象类
class Serializable {
public:
virtual string serialize() const = 0;
virtual void deserialize(const string& data) = 0;
virtual ~Serializable() = default;
};
// 实现多个接口
class Shape : public Drawable, public Serializable {
protected:
double x, y; // 位置
public:
Shape(double x = 0, double y = 0) : x(x), y(y) {}
// 必须实现所有纯虚函数
void draw() const override {
cout << "在位置(" << x << ", " << y << ")绘制形状" << endl;
}
void resize(double factor) override {
cout << "缩放因子: " << factor << endl;
}
string serialize() const override {
return "Shape(" + to_string(x) + "," + to_string(y) + ")";
}
void deserialize(const string& data) override {
// 解析数据
cout << "反序列化: " << data << endl;
}
};
// 具体形状类
class Circle : public Shape {
private:
double radius;
public:
Circle(double x, double y, double r) : Shape(x, y), radius(r) {}
void draw() const override {
cout << "在位置(" << x << ", " << y << ")绘制圆形,半径: " << radius << endl;
}
void resize(double factor) override {
radius *= factor;
}
string serialize() const override {
return "Circle(" + to_string(x) + "," + to_string(y) + "," + to_string(radius) + ")";
}
};
int main() {
// 不能实例化抽象类
// Drawable d; // 错误
// 可以使用抽象类指针
Drawable* drawable = new Circle(10, 20, 5);
drawable->draw();
drawable->showInfo();
delete drawable;
// 使用接口
Serializable* serializable = new Circle(0, 0, 10);
string data = serializable->serialize();
cout << "\n序列化数据: " << data << endl;
serializable->deserialize(data);
delete serializable;
return 0;
}运算符重载
cpp
#include <iostream>
#include <string>
using namespace std;
class Complex {
private:
double real;
double imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// 获取器
double getReal() const { return real; }
double getImag() const { return 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);
}
// 成员函数重载 *(复数乘法)
Complex operator*(const Complex& other) const {
return Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real
);
}
// ============ 复合赋值运算符 ============
Complex& operator+=(const Complex& other) {
real += other.real;
imag += other.imag;
return *this;
}
// ============ 一元运算符 ============
// 负号
Complex operator-() const {
return Complex(-real, -imag);
}
// ============ 比较运算符 ============
bool operator==(const Complex& other) const {
return real == other.real && imag == other.imag;
}
bool operator!=(const Complex& other) const {
return !(*this == other);
}
// ============ 自增运算符 ============
// 前置++
Complex& operator++() {
++real;
return *this;
}
// 后置++(int参数区分)
Complex operator++(int) {
Complex temp = *this;
++real;
return temp;
}
// ============ 下标运算符 ============
double& operator[](int index) {
if (index == 0) return real;
return imag;
}
// ============ 类型转换 ============
// 转换为double(模)
operator double() const {
return sqrt(real * real + imag * imag);
}
// ============ 输入输出运算符(友元函数) ============
friend ostream& operator<<(ostream& os, const Complex& c);
friend istream& operator>>(istream& is, Complex& c);
};
// 输出运算符
ostream& operator<<(ostream& os, const Complex& c) {
os << c.real;
if (c.imag >= 0) os << "+";
os << c.imag << "i";
return os;
}
// 输入运算符
istream& operator>>(istream& is, Complex& c) {
cout << "输入实部: ";
is >> c.real;
cout << "输入虚部: ";
is >> c.imag;
return is;
}
int main() {
Complex c1(3, 4);
Complex c2(1, 2);
cout << "c1 = " << c1 << endl;
cout << "c2 = " << c2 << endl;
// 算术运算
cout << "\nc1 + c2 = " << (c1 + c2) << endl;
cout << "c1 - c2 = " << (c1 - c2) << endl;
cout << "c1 * c2 = " << (c1 * c2) << endl;
// 复合赋值
Complex c3 = c1;
c3 += c2;
cout << "c1 += c2 = " << c3 << endl;
// 一元运算
cout << "-c1 = " << (-c1) << endl;
// 比较运算
cout << "\nc1 == c2: " << (c1 == c2) << endl;
cout << "c1 != c2: " << (c1 != c2) << endl;
// 自增运算
Complex c4(1, 1);
cout << "\n++c4 = " << (++c4) << endl;
cout << "c4++ = " << (c4++) << endl;
cout << "c4 = " << c4 << endl;
// 下标运算
c1[0] = 10;
c1[1] = 20;
cout << "\nc1[0] = " << c1[0] << ", c1[1] = " << c1[1] << endl;
// 类型转换
double magnitude = c1;
cout << "\n|c1| = " << magnitude << endl;
return 0;
}本章小结
本章学习了:
- 继承:公有、保护、私有继承
- 多态:虚函数、动态绑定
- 抽象类:纯虚函数、接口
- 运算符重载:算术、比较、输入输出运算符
下一章,我们将学习模板,了解C++泛型编程。
