C++对象的四大基本特性

devtools/2024/11/23 16:08:24/

在面向对象编程(Object-Oriented Programming, OOP)中,对象的四大基本特性是对象唯一性(Identity)、分类性(Classification)、继承性(Inheritance)和多态性(Polymorphism)。这些特性是理解和设计面向对象系统的基础。

### 1. 对象唯一性(Identity)

**概念**:
- 每个对象都有一个唯一的标识符,这个标识符在对象的生命周期内保持不变,即使对象的状态发生变化。这个标识符通常由内存地址实现。
- 不同的对象即使状态相同,它们的标识符也不同。

**示例**:
在C++中,可以通过对象的内存地址来表示唯一性。使用`&`运算符可以获得对象的地址。

```cpp
#include <iostream>

class MyClass {
public:
    int value;
    MyClass(int val) : value(val) {}
};

int main() {
    MyClass obj1(10);
    MyClass obj2(10);

    std::cout << "Address of obj1: " << &obj1 << std::endl;
    std::cout << "Address of obj2: " << &obj2 << std::endl;

    return 0;
}
```

在这个例子中,`obj1`和`obj2`的值相同,但它们的地址(标识符)不同。

### 2. 分类性(Classification)

**概念**:
- 对象具有一致的数据结构(属性)和行为(方法),这些相似的对象可以被抽象为类(Class)。
- 类是对一组对象的抽象描述,定义了对象的属性和行为。

**示例**:
在C++中,类的定义如下:

```cpp
class Animal {
public:
    std::string name;
    int age;

    void speak() {
        std::cout << name << " says: Hello!" << std::endl;
    }
};
```

在这个例子中,`Animal`类定义了一组具有`name`和`age`属性以及`speak`行为的对象。

### 3. 继承性(Inheritance)

**概念**:
- 继承性允许一个类(子类)继承另一个类(父类)的属性和方法,子类可以重用父类的代码,并可以扩展或修改父类的行为。
- 继承促进了代码重用和层次化设计。

**示例**:
在C++中,继承通过`:`实现:

```cpp
class Dog : public Animal {
public:
    void bark() {
        std::cout << name << " says: Woof!" << std::endl;
    }
};
```

在这个例子中,`Dog`类继承了`Animal`的属性和方法,并增加了一个新的方法`bark`。

### 4. 多态性(Polymorphism)

**概念**:
- 多态性允许相同的操作作用于不同类型的对象并产生不同的结果。
- 通过多态性,可以在父类引用或指针上调用子类的方法,具体调用哪个方法由对象的实际类型决定。

**示例**:
在C++中,多态性通常通过虚函数实现:

```cpp
class Animal {
public:
    virtual void speak() {
        std::cout << "Animal speaks." << std::endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {
        std::cout << "Dog barks." << std::endl;
    }
};

int main() {
    Animal* animal = new Dog();
    animal->speak();  // 调用的是 Dog 的 speak 方法

    delete animal;
    return 0;
}
```

在这个例子中,`Animal`类的`speak`方法被声明为虚函数,`Dog`类重写了`speak`方法。当通过`Animal`类型的指针调用`speak`时,实际调用的是`Dog`类的`speak`方法。

### 多态性(Polymorphism)

**概念**:
多态性是面向对象编程的一个核心特性,它允许同一个接口表现出不同的行为。多态性通常通过继承(Inheritance)和虚函数(Virtual Function)来实现。在C++中,多态性可以分为编译时多态性(静态多态性)和运行时多态性(动态多态性)。

**先修知识**:
1. **继承**:子类继承父类的属性和方法,可以重载或重写父类的方法。
2. **虚函数**:在基类中使用`virtual`关键字声明的函数,允许在派生类中重写,并在运行时进行动态绑定。
3. **指针和引用**:通过基类的指针或引用来指向派生类对象。这是实现运行时多态性的关键。

### 编译时多态性

编译时多态性主要通过函数重载和模板实现。编译器在编译时决定调用哪个函数。

#### 示例:函数重载
```cpp
#include <iostream>

class Print {
public:
    void show(int i) {
        std::cout << "Integer: " << i << std::endl;
    }

    void show(double d) {
        std::cout << "Double: " << d << std::endl;
    }
};

int main() {
    Print printer;
    printer.show(10);    // 调用 show(int)
    printer.show(3.14);  // 调用 show(double)
    return 0;
}
```
- **函数重载**:`show`函数有两个版本,一个接受`int`参数,一个接受`double`参数。在编译时,根据传入参数的类型决定调用哪个版本。

### 运行时多态性

运行时多态性通过继承和虚函数来实现。在运行时,根据对象的实际类型调用相应的函数版本。

#### 示例:虚函数
```cpp
#include <iostream>

class Base {
public:
    virtual void display() const {  // 虚函数
        std::cout << "Display from Base" << std::endl;
    }
};

class Derived : public Base {
public:
    void display() const override {  // 重写父类的虚函数
        std::cout << "Display from Derived" << std::endl;
    }
};

int main() {
    Base* basePtr;
    Derived derivedObj;
    basePtr = &derivedObj;

    basePtr->display();  // 调用Derived的display()
    return 0;
}
```

**逐行解释**:
- `virtual void display() const {...}`:基类中的虚函数,允许子类重写。
- `void display() const override {...}`:派生类中的重写函数,`override`关键字增强代码可读性和安全性(C++11引入)。
- `Base* basePtr;`:声明一个基类指针。
- `basePtr = &derivedObj;`:基类指针指向派生类对象。
- `basePtr->display();`:调用派生类的`display()`,这是多态性的体现。由于`display()`是虚函数,运行时根据`basePtr`的实际指向对象(`derivedObj`)调用正确的函数版本。

### 应用场景

1. **接口的统一**:多态性允许不同的类实现相同的接口方法,从而使代码更加灵活和可扩展。
2. **库和框架设计**:在设计库和框架时,经常使用多态性来定义灵活的接口,允许用户定义自定义行为。
3. **事件驱动编程**:在GUI和游戏开发中,多态性用于处理不同的事件和用户交互。

### 类似题目设计

**题目**:设计一个动物类`Animal`,并派生两个类`Dog`和`Cat`,每个类都实现一个`makeSound`方法:`Dog`类输出"Woof!",`Cat`类输出"Meow!"。在`main`函数中,使用基类指针调用派生类的方法,展示多态性。

**思路**:
1. 定义基类`Animal`,并声明一个虚函数`makeSound`。
2. 定义派生类`Dog`和`Cat`,分别重写`makeSound`。
3. 在`main`中创建`Dog`和`Cat`对象,并使用`Animal`指针调用。

**代码**:
```cpp
#include <iostream>
#include <vector>  // 用于存储对象指针的容器

class Animal {
public:
    virtual void makeSound() const {  // 虚函数
        std::cout << "Some generic animal sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() const override {  // 重写makeSound
        std::cout << "Woof!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void makeSound() const override {  // 重写makeSound
        std::cout << "Meow!" << std::endl;
    }
};

int main() {
    std::vector<Animal*> animals;  // 创建一个Animal指针的向量
    Dog dog;
    Cat cat;

    animals.push_back(&dog);
    animals.push_back(&cat);

    for (Animal* animal : animals) {
        animal->makeSound();  // 调用实际对象的makeSound
    }

    return 0;
}
```

**逐行注释**:
- `class Animal {...}`:定义基类`Animal`。
- `virtual void makeSound() const {...}`:声明虚函数`makeSound`。
- `class Dog : public Animal {...}`:定义派生类`Dog`。
- `void makeSound() const override {...}`:在`Dog`中重写`makeSound`。
- `class Cat : public Animal {...}`:定义派生类`Cat`。
- `std::vector<Animal*> animals;`:创建一个存储`Animal`指针的向量。
- `animals.push_back(&dog);`:将`Dog`对象的地址添加到向量中。
- `animals.push_back(&cat);`:将`Cat`对象的地址添加到向量中。
- `for (Animal* animal : animals) {...}`:遍历向量,调用每个对象的`makeSound`方法。

通过这种方式,我们展示了多态性的强大之处:使用统一的接口来处理不同类型的对象。这种灵活性使得程序更具扩展性和可维护性。希望这些信息对你理解多态性有所帮助!如果你有任何疑问或需要进一步解释,请随时告知。

 


http://www.ppmy.cn/devtools/136329.html

相关文章

【AIGC】大模型面试高频考点-显存占用

【AIGC】大模型面试高频考点-显存占用 &#xff08;1&#xff09;显存占用-训练阶段&#xff08;2&#xff09;显存占用-推理阶段 &#xff08;1&#xff09;显存占用-训练阶段 &#xff08;2&#xff09;显存占用-推理阶段

Linux 查看端口和进程的常用命令(下)

htop 命令 htop 是 top 命令的增强版本&#xff0c;提供了更友好的交互界面&#xff0c;并且支持使用键盘快捷键操作。默认情况下&#xff0c;htop 没有安装&#xff0c;你可以通过以下命令安装它&#xff1a; bash sudo apt install htop # 在Debian/Ubuntu系统上 sudo yum …

对抗样本存在的原因

对抗样本存在的原因与深度学习模型的结构和训练机制密切相关&#xff0c;主要包括以下几个方面&#xff1a; 1. 模型的高维性和线性化行为 高维性&#xff1a;深度学习模型通常在高维空间中运行&#xff0c;而高维空间中的数据分布非常稀疏。微小的扰动在高维空间可能被放大&a…

MySQL性能分析工具的使用

目录 1.查看系统性能参数 2.统计SQL的查询成本&#xff1a;last_query_cost 3.定位执行慢的 SQL&#xff1a;慢查询日志 3.1开启慢查询日志参数 1.开启slow_query_log 2. 修改long_query_time阈值 3.2 查看慢查询数目 4.查看 SQL 执行成本&#xff1a;SHOW PROFILE 5.…

泷羽sec-星河飞雪-shell-6

免责声明 学习视频来自 B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 泷羽sec官网&#xff1a;http…

操作系统——揭开盖子

计算机执行时——取指执行 es:bx等于从0x9000开始&#xff0c;到0x90200结束

自适应安全框架(ASA)在网络安全2.0新防御体系中的应用

随着云计算、大数据、移动互联、物联网等新技术的成熟&#xff0c;社交网络、电子商务、智慧城市的发展&#xff0c;已经使人们的生活全面走进了由网络所构建的虚拟世界。 随着网络承载的事务越来越丰富&#xff0c;其所面临的安全威胁也越来越多&#xff0c;针对关键信息基础…

洛谷P2249 【深基13.例1】查找

【深基13.例1】查找 题目描述 输入 n n n 个不超过 1 0 9 10^9 109 的单调不减的&#xff08;就是后面的数字不小于前面的数字&#xff09;非负整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_{n} a1​,a2​,…,an​&#xff0c;然后进行 m m m 次询问。对于每次询问&#x…