C++ 类和对象(二)

简介: C++ 类和对象(二)

抽象类(abstract class)是一种不能被实例化的类,它仅仅用于提供接口和基础实现,并且要求子类必须实现某些方法。在C++中,可以通过将一个或多个成员函数声明为纯虚函数(pure virtual function)来定义抽象类。

下面是一个简单的抽象类示例:

```cpp
class Animal {
public:
    virtual void makeSound() = 0; // 声明纯虚函数
};
class Dog : public Animal {
public:
    void makeSound() override { // 实现纯虚函数
        cout << "Woof!" << endl;
    }
};
class Cat : public Animal {
public:
    void makeSound() override { // 实现纯虚函数
        cout << "Meow!" << endl;
    }
};
int main() {
    Animal* animals[2];
    animals[0] = new Dog();
    animals[1] = new Cat();
    for (int i = 0; i < 2; i++) {
        animals[i]->makeSound(); // 动态绑定
    }
    return 0;
}
```

在这个示例中,我们定义了一个名为Animal的抽象类,它有一个纯虚函数makeSound,用于发出声音。然后,我们定义了两个子类Dog和Cat,并分别实现了makeSound函数。在main函数中,我们创建了两个Animal指针对象,并将其指向不同的子类对象,以实现多态性。

总之,C++中的类还有许多其他高级特性,例如多态、虚函数和抽象类等。这些特性可以帮助程序员编写出更加灵活、可扩展的代码,提高开发效率和可维护性。掌握这些特性可以使得程序员写出更加优秀的代码,并有利于职业发展。除了上述特性,C++中的类还有一些其他的高级特性,例如多态、虚函数和抽象类等。

多态(polymorphism)是一种面向对象编程的基本概念,它可以使得不同类型的对象表现出相同的行为。在C++中,多态性主要通过虚函数(virtual function)来实现。

虚函数是一种特殊的成员函数,它可以被子类重写,并且在运行时动态绑定到正确的函数,以实现多态性。使用虚函数可以让程序更加灵活,可扩展性更好。

下面是一个简单的虚函数示例:

```cpp
class Shape {
public:
    virtual double getArea() { // 声明虚函数
        return 0;
    }
};
class Rectangle : public Shape {
private:
    double width, height;
public:
    Rectangle(double w, double h) {
        width = w;
        height = h;
    }
    double getArea() override { // 重写虚函数
        return width * height;
    }
};
class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) {
        radius = r;
    }
    double getArea() override { // 重写虚函数
        return 3.1415926 * radius * radius;
    }
};
int main() {
    Shape* shapes[2];
    shapes[0] = new Rectangle(3, 4);
    shapes[1] = new Circle(5);
    for (int i = 0; i < 2; i++) {
        cout << "Area of Shape " << i + 1 << " is: " << shapes[i]->getArea() << endl; // 动态绑定
    }
    return 0;
}
```

在这个示例中,我们定义了一个名为Shape的基类,它有一个虚函数getArea,用于计算面积。然后,我们定义了两个子类Rectangle和Circle,分别重写了getArea函数。在main函数中,我们创建了两个Shape指针对象,并将其指向不同的子类对象,以实现多态性。

抽象类(abstract class)是一种不能被实例化的类,它仅仅用于提供接口和基础实现,并且要求子类必须实现某些方法。在C++中,可以通过将一个或多个成员函数声明为纯虚函数(pure virtual function)来定义抽象类。

下面是一个简单的抽象类示例:

```cpp
class Animal {
public:
    virtual void makeSound() = 0; // 声明纯虚函数
};
class Dog : public Animal {
public:
    void makeSound() override { // 实现纯虚函数
        cout << "Woof!" << endl;
    }
};
class Cat : public Animal {
public:
    void makeSound() override { // 实现纯虚函数
        cout << "Meow!" << endl;
    }
};
int main() {
    Animal* animals[2];
    animals[0] = new Dog();
    animals[1] = new Cat();
    for (int i = 0; i < 2; i++) {
        animals[i]->makeSound(); // 动态绑定
    }
    return 0;
}
```

在这个示例中,我们定义了一个名为Animal的抽象类,它有一个纯虚函数makeSound,用于发出声音。然后,我们定义了两个子类Dog和Cat,并分别实现了makeSound函数。在main函数中,我们创建了两个Animal指针对象,并将其指向不同的子类对象,以实现多态性。

总之,C++中的类还有许多其他高级特性,例如多态、虚函数和抽象类等。这些特性可以帮助程序员编写出更加灵活、可扩展的代码,提高开发效率和可维护性。掌握这些特性可以使得程序员写出更加优秀的代码,并有利于职业发展。除了上述特性,C++中的类还有一些其他的高级特性,例如移动语义、智能指针和并发编程等。

移动语义(move semantics)是一种用于优化对象拷贝和赋值操作的技术。在C++11之前,对象的拷贝和赋值都是通过复制构造函数(copy constructor)和赋值运算符(assignment operator)来实现的,这会导致创建新对象和销毁旧对象,从而浪费时间和资源。使用移动语义可以避免这些问题,提高效率和性能。

下面是一个简单的移动语义示例:

```cpp
class String {
private:
    char* data; // 字符串数据
public:
    String(const char* str) { // 构造函数
        int len = strlen(str);
        data = new char[len + 1];
        strcpy(data, str);
    }
    String(String&& other) { // 移动构造函数
        data = other.data;
        other.data = nullptr;
    }
    ~String() { // 析构函数
        if (data) {
            delete[] data;
        }
    }
};
int main() {
    String s1 = "hello";
    String s2 = std::move(s1); // 使用移动构造函数
    return 0;
}
```

在这个示例中,我们定义了一个名为String的类,它有一个构造函数、一个移动构造函数和一个析构函数。在main函数中,我们创建了两个String对象s1和s2,并使用std::move函数将s1移动到s2中,以实现移动语义。

智能指针(smart pointer)是一种自动化管理内存的技术,可以避免内存泄漏和野指针等问题。在C++中,智能指针主要有三种类型:unique_ptr、shared_ptr和weak_ptr,分别用于实现独占所有权、共享所有权和弱引用。

下面是一个简单的智能指针示例:

```cpp
class Person {
public:
    string name;
    int age;
    Person(string n, int a) : name(n), age(a) {}
};
int main() {
    unique_ptr<Person> p1(new Person("Alice", 18)); // 使用unique_ptr
    shared_ptr<Person> p2 = make_shared<Person>("Bob", 20); // 使用shared_ptr
    weak_ptr<Person> p3(p2); // 使用weak_ptr
    if (auto sp = p3.lock()) { // 使用lock函数获取shared_ptr
        cout << sp->name << " is " << sp->age << " years old." << endl;
    }
    return 0;
}
```

在这个示例中,我们定义了一个名为Person的类,它有一个构造函数和两个成员变量(name和age)。然后,在main函数中,我们使用unique_ptr和shared_ptr分别创建了两个Person对象p1和p2,并使用weak_ptr创建了一个弱引用p3。最后,我们使用lock函数获取p3对应的shared_ptr,并输出其中的信息。

并发编程(concurrency programming)是一种利用多线程技术来提高程序性能和响应速度的编程范式。在C++中,可以使用std::thread、std::mutex、std::condition_variable等类来实现多线程编程和同步机制。

下面是一个简单的并发编程示例:

```cpp
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int counter = 0;
mutex mtx; // 定义互斥锁
void increment() {
    for (int i = 0; i < 100000; i++) {
        unique_lock<mutex> lock(mtx); // 加锁
        counter++; // 计数器自增
    }
}
int main() {
    thread t1(increment);
    thread t2(increment);
    t1.join();
    t2.join();
    cout << "The value of counter is: " << counter << endl;
    return 0;
}
```

在这个示例中,我们定义了一个名为counter的全局变量,并使用std::mutex类定义了一个互斥锁mtx。然后,我们定义了一个名为increment的函数,它包含一个循环,用于将计数器自增。在该函数中,我们使用unique_lock类对互斥锁进行加锁操作,以保证线程安全。最后,在main函数中,我们创建了两个线程t1和t2,分别调用increment函数,并使用join函数等待线程结束。最终,我们输出了计数器的值。

总之,C++中的类还有许多其他高级特性,例如移动语义、智能指针和并发编程等。这些特性可以帮助程序员编写出更加高效、安全的代码,提高开发效率和可维护性。掌握这些特性可以让程序员写出更加优秀的代码,并有利于职业发展。另外,C++中的模板(template)也是一项非常重要的特性。模板可以将函数或类的实现与其所操作的数据类型分离开来,从而实现代码复用和泛型编程。

在C++中,有两种类型的模板:函数模板和类模板。函数模板是一种通用的函数定义,可以用于多种不同类型的参数。类模板是一种通用的类定义,可以用于多种不同类型的成员变量和成员函数。

下面是一个简单的函数模板示例:

```cpp
template <typename T>
T max(T a, T b) {
    return a > b ? a : b;
}
int main() {
    int x = 1, y = 2;
    double d1 = 1.5, d2 = 2.5;
    cout << "The max of " << x << " and " << y << " is " << max(x, y) << endl;
    cout << "The max of " << d1 << " and " << d2 << " is " << max(d1, d2) << endl;
    return 0;
}
```

在这个示例中,我们定义了一个名为max的函数模板,它接受两个参数a和b,并返回其中较大的值。参数类型使用typename关键字进行声明。然后,在main函数中,我们调用了max函数,并传入了不同类型的参数。由于max是一个函数模板,它能够自动适应不同类型的参数,并返回正确的结果。

下面是一个简单的类模板示例:

```cpp
template <typename T>
class Array {
private:
    T* data;
    int size;
public:
    Array(int n) : size(n) {
        data = new T[n];
    }
    T& operator[](int index) {
        if (index >= 0 && index < size) {
            return data[index];
        } else {
            throw out_of_range("Index out of range!");
        }
    }
    ~Array() {
        delete[] data;
    }
};
int main() {
    Array<int> arr1(5);
    for (int i = 0; i < 5; i++) {
        arr1[i] = i * i;
    }
    Array<double> arr2(3);
    arr2[0] = 1.0;
    arr2[1] = 2.0;
    arr2[2] = 3.0;
    cout << "The values in arr1 are: ";
    for (int i = 0; i < 5; i++) {
        cout << arr1[i] << " ";
    }
    cout << endl;
    cout << "The values in arr2 are: ";
    for (int i = 0; i < 3; i++) {
        cout << arr2[i] << " ";
    }
    cout << endl;
    return 0;
}
```

在这个示例中,我们定义了一个名为Array的类模板,它有一个私有成员变量data和一个公有成员函数operator[],用于访问和修改数组元素。在main函数中,我们创建了两个不同类型的Array对象arr1和arr2,并使用operator[]函数对其元素进行操作。由于Array是一个类模板,它能够适应不同类型的数据,并正确地执行相应的操作。

总之,C++中的模板是一项非常重要的特性,可以实现代码复用和泛型编程。函数模板和类模板都能够自动适应不同类型的数据,并执行相应的操作。掌握模板技术可以让程序员编写出更加灵活、通用的代码,提高开发效率和可维护性。

目录
相关文章
|
7月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
3月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
89 0
|
3月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
167 0
|
5月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
175 12
|
6月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
127 16
|
6月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
6月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
6月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
342 6
|
6月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
7月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)