<c++基础(1)>实现一个合格的自定义类

实现一个合格的自定义类

Effective C++ 条款19中指明了合格自定义类应该包含的设计规范,以下是一些关键的思考点和设计考虑,以帮助设计一个新的自定义类:

  1. 对象的创建和销毁:
    • 构造函数应该负责对象的初始化,可以有多个构造函数以支持不同的初始化方式。
    • 析构函数用于释放对象所占用的资源,如动态分配的内存等。
  2. 对象的初始化和赋值的差异:
    • 初始化是在对象创建时进行的,构造函数负责初始化对象的状态。
    • 赋值是将一个对象的值复制给另一个对象,赋值操作符重载函数负责定义对象的赋值行为。
  3. 值传递的影响:
    • 如果对象被按值传递,会调用拷贝构造函数来创建传递的副本。
  4. 合法值和约束条件:
    • 对于类的成员变量,应该定义它们的合法取值范围,以及确保对象的不变量。
    • 构造函数、赋值操作符和setter函数应该进行错误检查,确保输入的值符合约束条件。
  5. 继承关系:
    • 如果你的类需要作为基类,需要考虑是否需要将析构函数声明为虚函数,以支持多态性。
    • 如果允许其他类继承你的类,需要考虑基类的设计对派生类的影响,特别是虚函数的处理。
  6. 类型转换:
    • 根据需要,可以定义类型转换函数或构造函数,以支持对象与其他类型的转换。
  7. 合理的操作符和函数:
    • 根据类的功能和需求,声明适当的成员函数和操作符重载函数。
  8. 标准函数的声明:
    • 根据需要,将一些函数声明为私有成员,以控制外部访问。
  9. 成员的访问控制:
    • 决定哪些成员应该是公有、保护或私有的,以及是否需要友元类或函数。
  10. 未声明接口:
    • 考虑效率、异常安全性以及资源管理方面的保证,以确保类的实现符合预期的约束条件。
  11. 泛化:
    • 如果你要定义一整个类型家族,可能需要考虑使用类模板而不是单独的类来实现。

在设计新的自定义类时,仔细考虑以上问题,可以帮助你建立一个合理、健壮和易于使用的类。

提供一个简单的C++类的例子,以演示如何根据前述的设计考虑实现一个自定义类。这个例子是一个表示有理数(Rational Number)的类,包含构造函数、析构函数、拷贝构造函数、加法、减法、乘法、除法操作符重载,以及显式和隐式转换。

cpp 复制代码
#include <iostream>

class Rational {
private:
    int numerator;
    int denominator;

public:
    // 构造函数
    Rational(int num = 0, int denom = 1) : numerator(num), denominator(denom) {
        if (denominator == 0) {
            std::cerr << "Error: Denominator cannot be zero." << std::endl;
            // 处理错误情况,可以设置默认值或抛出异常
            numerator = 0;
            denominator = 1;
        }
    }

    // 拷贝构造函数
    Rational(const Rational& other) : numerator(other.numerator), denominator(other.denominator) {}

    // 析构函数
    ~Rational() {
        // 可以在这里执行清理工作
    }

    // 加法操作符重载
    Rational operator+(const Rational& other) const {
        int resultNumerator = numerator * other.denominator + other.numerator * denominator;
        int resultDenominator = denominator * other.denominator;
        return Rational(resultNumerator, resultDenominator);
    }

    // 减法操作符重载
    Rational operator-(const Rational& other) const {
        int resultNumerator = numerator * other.denominator - other.numerator * denominator;
        int resultDenominator = denominator * other.denominator;
        return Rational(resultNumerator, resultDenominator);
    }

    // 乘法操作符重载
    Rational operator*(const Rational& other) const {
        int resultNumerator = numerator * other.numerator;
        int resultDenominator = denominator * other.denominator;
        return Rational(resultNumerator, resultDenominator);
    }

    // 除法操作符重载
    Rational operator/(const Rational& other) const {
        // 避免除零错误
        if (other.numerator != 0) {
            int resultNumerator = numerator * other.denominator;
            int resultDenominator = denominator * other.numerator;
            return Rational(resultNumerator, resultDenominator);
        } else {
            std::cerr << "Error: Division by zero." << std::endl;
            return Rational(); // 返回一个默认值或抛出异常
        }
    }

    // 显式转换为double类型
    explicit operator double() const {
        return static_cast<double>(numerator) / static_cast<double>(denominator);
    }

    // 输出有理数
    friend std::ostream& operator<<(std::ostream& os, const Rational& rational) {
        os << rational.numerator << "/" << rational.denominator;
        return os;
    }
};

int main() {
    Rational num1(1, 2);
    Rational num2(3, 4);

    Rational sum = num1 + num2;
    Rational difference = num1 - num2;
    Rational product = num1 * num2;
    Rational quotient = num1 / num2;

    std::cout << "Sum: " << sum << std::endl;
    std::cout << "Difference: " << difference << std::endl;
    std::cout << "Product: " << product << std::endl;
    std::cout << "Quotient: " << quotient << std::endl;

    double result = static_cast<double>(num1); // 显式转换为double
    std::cout << "Double Value: " << result << std::endl;

    return 0;
}
相关推荐
杨荧13 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰19 分钟前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
小芒果_0124 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
gkdpjj30 分钟前
C++优选算法十 哈希表
c++·算法·散列表
王俊山IT32 分钟前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
为将者,自当识天晓地。34 分钟前
c++多线程
java·开发语言
-Even-34 分钟前
【第六章】分支语句和逻辑运算符
c++·c++ primer plus
小政爱学习!36 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
神奇夜光杯1 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长