承接Qt/C++软件开发项目,高质量交付,灵活沟通,长期维护支持。需求所寻,技术正适,共创完美,欢迎联系(微信:wid_ljh)!
C++ 是一种支持面向对象编程(OOP)的语言,提供了丰富的特性来实现代码的复用和扩展。其中,重载(Overloading)、多态(Polymorphism)和继承(Inheritance)是 OOP 的三大核心特性。
重载是指在同一个作用域内定义多个同名函数或运算符,但它们的参数列表不同。编译器根据调用时提供的参数类型和数量来选择合适的版本。因此,重载的核心在于参数签名的不同。
#include
void print(int x) {
std::cout << "Integer: " << x << "\n";
}
void print(double x) {
std::cout << "Double: " << x << "\n";
}
void print(int x, int y) {
std::cout << "Two integers: " << x << ", " << y << "\n";
}
int main() {
print(42); // 调用第一个print
print(3.14); // 调用第二个print
print(1, 2); // 调用第三个print
return 0;
}
class Complex {
public:
double real, imag;
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
Complex operator+(const Complex& rhs) const {
return Complex(real + rhs.real, imag + rhs.imag);
}
};
int main() {
Complex c1(1, 2), c2(3, 4);
Complex c3 = c1 + c2;
std::cout << "Result: (" << c3.real << ", " << c3.imag << ")\n";
return 0;
}
继承允许一个类(派生类)从另一个类(基类)继承属性和行为,从而实现代码复用。C++ 支持单继承和多继承。
class Vehicle {
public:
void start() { std::cout << "Vehicle started.\n"; }
};
class Car : public Vehicle {
public:
void drive() { std::cout << "Car is driving.\n"; }
};
int main() {
Car myCar;
myCar.start(); // 继承自Vehicle的方法
myCar.drive(); // Car自己的方法
return 0;
}
class Engine {
public:
void startEngine() { std::cout << "Engine started.\n"; }
};
class Wheel {
public:
void rotateWheel() { std::cout << "Wheel rotated.\n"; }
};
class Car : public Engine, public Wheel {
public:
void drive() { std::cout << "Car is driving.\n"; }
};
int main() {
Car myCar;
myCar.startEngine(); // 继承自Engine的方法
myCar.rotateWheel(); // 继承自Wheel的方法
myCar.drive(); // Car自己的方法
return 0;
}
C++ 提供了三种访问控制修饰符:public、protected 和 private,用于控制类成员的可见性。
class Base {
protected:
int protectedData;
private:
int privateData;
public:
void setProtectedData(int data) { protectedData = data; }
void setPrivateData(int data) { privateData = data; }
int getProtectedData() const { return protectedData; }
int getPrivateData() const { return privateData; }
};
class Derived : public Base {
public:
void displayProtectedData() const { std::cout << "Protected Data: " << protectedData << "\n"; }
// 无法直接访问privateData
};
派生类的构造函数可以调用基类的构造函数进行初始化,并且需要确保所有基类的构造函数都得到调用。
class Base {
public:
Base(int x) : m_x(x) { std::cout << "Base constructor called.\n"; }
protected:
int m_x;
};
class Derived : public Base {
public:
Derived(int x, int y) : Base(x), m_y(y) { std::cout << "Derived constructor called.\n"; }
~Derived() { std::cout << "Derived destructor called.\n"; }
private:
int m_y;
};
int main() {
Derived d(1, 2);
return 0;
}
并非所有情况下都应该使用继承。有时候,组合模式(Composition)更合适,即通过包含其他类的对象来实现功能,而不是通过继承。组合提高了模块化和灵活性,减少了代码耦合。
class Engine {
public:
void start() { std::cout << "Engine started\n"; }
};
class Car {
private:
Engine engine;
public:
void startCar() {
engine.start(); // 使用组合的方式调用Engine的方法
std::cout << "Car started\n";
}
};
int main() {
Car car;
car.startCar();
return 0;
}
多态性指的是同一接口可以有多种实现方式。C++ 主要通过虚函数(virtual function)实现动态多态性,即运行时多态。
#include
#include
class Shape {
public:
virtual double area() const = 0; // 纯虚函数
virtual ~Shape() {} // 虚析构函数
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override { return 3.14159 * radius * radius; }
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override { return width * height; }
};
void processShapes(const std::vector>& shapes) {
for (const auto& shape : shapes) {
std::cout << "Area: " << shape->area() << "\n";
}
}
int main() {
std::vector> shapes;
shapes.push_back(std::make_unique(5.0));
shapes.push_back(std::make_unique(4.0, 6.0));
processShapes(shapes);
return 0;
}
当一个类中声明了虚函数后,编译器会为该类创建一个虚函数表(vtable),每个对象都有一个指向这个表的指针(vptr)。当通过基类指针或引用来调用虚函数时,程序会在运行时查找 vtable,找到正确的派生类实现。
抽象类包含纯虚函数,不能实例化,通常用于定义接口。接口是一种特殊的抽象类,所有成员均为纯虚函数,适用于定义一组相关的行为规范。
class Drawable {
public:
virtual void draw() const = 0; // 定义绘图接口
virtual ~Drawable() {}
};
class Square : public Drawable {
public:
void draw() const override { std::cout << "Drawing square\n"; }
};