多态
多态(Polymorphism)是C++面向对象编程的一个关键概念,它允许你以一种通用的方式处理不同类型的对象,而无需了解它们的具体类型。C++中的多态性通过虚函数(virtual functions)来实现,主要包括两种形式:
多态是一种让你能够以相同的方式处理不同对象的编程概念。这意味着你可以使用相同的代码来处理不同类型的东西,而不需要知道它们的确切类型。
举个例子,想象你有一个玩具箱,里面装着不同类型的玩具,如汽车、娃娃和飞机。多态就像是一种魔法,让你可以使用相同的方式(例如,按下一个按钮)来玩不同类型的玩具,而不用关心你手中拿的到底是什么。无论你按下按钮的对象是汽车、娃娃还是飞机,都会有不同的响应。这就是多态的简单示例,它让你以一种通用的方式处理不同类型的对象。
#include <iostream>
class Animal {
public:
void makeSound()
{
std::cout << "动物发出声音" << std::endl;
}
};
class Dog : public Animal {
public:
void makeSound()
{
std::cout << "狗发出汪汪的声音" << std::endl;
}
};
class Cat : public Animal {
public:
void makeSound()
{
std::cout << "猫发出喵喵的声音" << std::endl;
}
};
int main() {
Animal* myAnimal;
Dog myDog;
Cat myCat;
myAnimal = &myDog;
myAnimal->makeSound(); // 调用狗的声音
myAnimal = &myCat;
myAnimal->makeSound(); // 调用猫的声音
return 0;
}
会输出:
动物发出声音
动物发出声音
添加上关键字virtual
#include <iostream>
class Animal {
public:
virtual void makeSound()
{
std::cout << "动物发出声音" << std::endl;
}
};
class Dog : public Animal {
public:
virtual void makeSound()
{
std::cout << "狗发出汪汪的声音" << std::endl;
}
};
class Cat : public Animal {
public:
virtual void makeSound()
{
std::cout << "猫发出喵喵的声音" << std::endl;
}
};
int main() {
Animal* myAnimal;
Dog myDog;
Cat myCat;
myAnimal = &myDog;
myAnimal->makeSound(); // 调用狗的声音
myAnimal = &myCat;
myAnimal->makeSound(); // 调用猫的声音
return 0;
}
输出:
狗发出汪汪的声音
猫发出喵喵的声音
虚函数和纯虚函数的区别:
虚函数:虚函数允许在基类中定义一个函数,然后在派生类中提供不同的实现,这允许你以一致的方式调用不同类的同名函数;说白了就是定义一个不为空的函数,在基类中实现。
纯虚函数:创建一个纯虚函数(pure virtual function)时,你不提供函数体的实现,而是在基类中声明该函数,以强制任何继承该基类的派生类提供自己的实现。
#include <iostream>
class Shape {
public:
// 声明一个纯虚函数
virtual void draw() = 0;
};
class Circle : public Shape {
public:
// 派生类必须提供实现
void draw() {
std::cout << "绘制圆形" << std::endl;
}
};
class Rectangle : public Shape {
public:
// 派生类必须提供实现
void draw() {
std::cout << "绘制矩形" << std::endl;
}
};
int main() {
Circle circle;
Rectangle rectangle;
circle.draw(); // 调用Circle类的draw函数
rectangle.draw(); // 调用Rectangle类的draw函数
return 0;
}
虚函数和函数重载的区别:
函数重载的决定因素是参数列表,而不是返回类型。参数列表必须在数量、类型或顺序上有所不同,以便区分重载的函数。
相同点:
多态性支持: 虚函数和函数重载都支持多态性,这意味着可以使用相同的函数名调用不同的函数,具体调用哪个函数取决于运行时的对象类型或函数参数的不同。
相同函数名: 在虚函数和函数重载中,可以使用相同的函数名来定义多个函数,但它们必须有不同的参数列表或参数类型。
不同点:
虚函数是面向对象的概念: 虚函数是面向对象编程中的一个重要概念,它与类的继承和多态性密切相关。虚函数是在基类中声明并在派生类中重写的函数,以便在运行时动态绑定到正确的函数实现。
函数重载是函数签名不同: 函数重载是指在同一作用域内定义多个具有相同函数名但不同参数列表的函数。函数重载是一种编译时多态,编译器在编译时根据参数列表的不同来选择调用正确的函数。
虚函数需要基类和派生类: 虚函数通常涉及到类的继承关系,其中基类声明虚函数,而派生类提供特定实现。函数重载不涉及类的继承,可以在同一类中或不同的作用域中定义重载函数。
虚函数需要指针或引用调用: 要实现虚函数的多态性,通常需要使用基类指针或引用来调用派生类对象的虚函数。函数重载则可以使用不同参数的函数名来直接调用不同函数。
总之,虚函数是一种用于实现运行时多态性的面向对象编程特性,而函数重载是一种用于在同一作用域内定义多个同名函数的编译时多态性特性。虚函数通常涉及类的继承关系,而函数重载不涉及类的继承。
构造函数的作用
对象初始化: 构造函数用于初始化类的对象,确保对象在创建后处于已知和一致的状态。它可以设置对象的成员变量,分配资源,或执行其他必要的初始化操作。
提供默认值: 构造函数可以为类的成员变量提供默认值,以确保对象在创建时具有合理的初始状态。这对于避免未初始化变量的问题非常有用。
资源分配和释放: 如果类需要管理资源(例如内存、文件句柄等),构造函数可以用来分配资源,而析构函数用于释放资源。这确保了资源的正确分配和释放,避免资源泄漏。
初始化成员: 构造函数可以用于初始化类的成员变量,包括调用其他构造函数来初始化基类或成员对象。
参数化对象: 构造函数可以接受参数,允许在创建对象时传递特定的初始化值,以满足不同对象的需求。这有助于实现对象的个性化初始化。
重载构造函数: 一个类可以有多个构造函数,每个构造函数可以接受不同的参数,以便在不同情况下执行不同的初始化操作。这称为构造函数重载。
构造函数的命名与类名相同,没有返回类型(包括不是void),通常使用成员初始化列表来初始化成员变量。在C++中,构造函数可以有默认参数,允许创建对象时省略某些参数,或提供自定义初始化。
总之,构造函数是用于初始化类对象的重要机制,它确保对象在创建时具有合适的状态,并有助于避免潜在的问题,如未初始化变量或资源泄漏