<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;
}
相关推荐
OTWOL2 分钟前
两道数组有关的OJ练习题
c语言·开发语言·数据结构·c++·算法
问道飞鱼6 分钟前
【前端知识】强大的js动画组件anime.js
开发语言·前端·javascript·anime.js
拓端研究室6 分钟前
R基于贝叶斯加法回归树BART、MCMC的DLNM分布滞后非线性模型分析母婴PM2.5暴露与出生体重数据及GAM模型对比、关键窗口识别
android·开发语言·kotlin
Code成立7 分钟前
《Java核心技术I》Swing的网格包布局
java·开发语言·swing
Auc2412 分钟前
使用scrapy框架爬取微博热搜榜
开发语言·python
QQ同步助手19 分钟前
C++ 指针进阶:动态内存与复杂应用
开发语言·c++
凯子坚持 c25 分钟前
仓颉编程语言深入教程:基础概念和数据类型
开发语言·华为
小爬虫程序猿27 分钟前
利用Java爬虫速卖通按关键字搜索AliExpress商品
java·开发语言·爬虫
程序猿-瑞瑞29 分钟前
24 go语言(golang) - gorm框架安装及使用案例详解
开发语言·后端·golang·gorm
qq_4335545430 分钟前
C++ 面向对象编程:递增重载
开发语言·c++·算法