C++——实现一个简单的vector(矢量)

基于《C++ Primer Plus》,进行了系统的构建。

vect.h

//
// Created by JAN on 2022/1/18.
//

#ifndef C___VECT_H
#define C___VECT_H
#include <iostream>

namespace VECTOR
{
    void menu();
    class Vector
    {
    public:
        enum Mode {RECT, POL};
    private:
        double x;
        double y;
        double mag;
        double ang;
        Mode mode;

        void set_mag();
        void set_ang();
        void set_x();
        void set_y();

    public:
        Vector();
        Vector(double n1, double n2, Mode form = RECT);
        void rest(double n1, double n2, Mode form = RECT);
        ~Vector();
        double xval() const { return x; }
        double yval() const { return y; }
        double magval() const { return mag; }
        double angval() const { return ang; }
        void polar_mode();
        void rect_mode();

        Vector operator+(const Vector &b) const;
        Vector operator-(const Vector &b) const;
        Vector operator-() const;
        Vector operator*(double n) const;

        friend Vector operator*(double n, const Vector &a);
        friend std::ostream& operator<<(std::ostream &os, const Vector &v);
        friend std::istream& operator>>(std::istream &is, Vector &v);
    };
}
#endif //C___VECT_H

vect.cpp

//
// Created by JAN on 2022/1/18.
//
#include <cmath>
#include "vect.h"

using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
using std::cin;

namespace VECTOR
{
    void menu()
    {
        cout << "0.退出程序\n";
        cout << "1.对向量进行输入\n";
        cout << "2.查看向量\n";
        cout << "3.改变向量模式\n";
        cout << "4.进行向量运算\n";
    }
    const double Rad_to_deg = 45.0 / atan(1.0);

    void Vector::set_mag()
    {
        mag = sqrt(x * x + y * y);
    }
    void Vector::set_ang()
    {
        if(x == 0 && y == 0){
            ang = 0;
        }else{
            ang = atan2(y,x);
        }
    }
    void Vector::set_x()
    {
        x = mag * cos(ang);
    }
    void Vector::set_y()
    {
        y = mag * sin(ang);
    }
     Vector::Vector()
     {
        mag = ang = x = y = 0;
        mode = RECT;
     }
     Vector::Vector(double n1, double n2, Mode form)
     {
        mode = form;
        if(form == RECT){
            x = n1;
            y = n2;
            set_mag();
            set_ang();
        }else if(mode == POL){
            mag = n1;
            ang = n2;
            set_x();
            set_y();
        }else{
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0;
            mode = RECT;
        }
     }

    void Vector::rest(double n1, double n2, Mode form)
    {
        mode = form;
        if(form == RECT){
            x = n1;
            y = n2;
            set_mag();
            set_ang();
        }else if(mode == POL){
            mag = n1;
            ang = n2;
            set_x();
            set_y();
        }else{
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = mag = ang = 0;
            mode = RECT;
        }
    }
     Vector::~Vector() = default;
     void Vector::polar_mode()
     {
        mode = POL;
     }
     void Vector::rect_mode()
     {
        mode = RECT;
     }

     Vector Vector::operator+(const Vector &b) const
     {
         return Vector{x + b.x, y + b.y};
     }
     Vector Vector::operator-(const Vector &b) const
     {
         return Vector{x - b.x, y - b.y};
     }
     Vector Vector::operator-() const
     {
        return Vector{-x, -y};
     }
     Vector Vector::operator*(double n) const
     {
        return Vector{x * n, y * n};
     }
     //friend
     Vector operator*(double n, const Vector &a)
     {
        return a * n;
     }
     std::ostream& operator<<(std::ostream &os, const Vector &v)
     {
        if(v.mode == Vector::RECT){
            os << "(x,y) = (" << v.x <<"," << v.y << ")";
        }else if(v.mode == Vector::POL){
            os << "(m,a) = (" << v.mag << "," << v.ang * Rad_to_deg <<")";
        }else{
            os << "Vector object mode is invalid";
        }
        return os;
     }
    std::istream& operator>>(std::istream &is, Vector &v)
    {
         double a,b;
         cin >> a >> b;
        if(v.mode == Vector::RECT){
            v.rest(a,b,Vector::RECT);
        }else if(v.mode == Vector::POL){
           v.rest(a,b,Vector::POL);
        }else{
            std::cout << "Vector object mode is invalid";
        }
        return is;
    }
}

 main.cpp

#include "vect.h"
using namespace VECTOR;
using std::string;
using std::cin;
using std::cout;
int main()
{
    const string rect = "rect";
    const string pol = "pol";
    int choose;
    Vector vec;
    string mode;
    int a,b;
    while(true)
    {
        menu();
        cout << "Which function: ";
        cin >> choose;
        if(!choose)  break;
        switch (choose) {
            case 1:
            {
                cout << "Which mode :";
                cin >> mode;
                if(mode == rect){
                    cout << "Please enter x and y: ";
                    cin >> a >> b;
                    vec.rest(a,b,Vector::RECT);
                }else if(mode == pol){
                    cout << "Please entre mag ang ang: ";
                    cin >> a >> b;
                    vec.rest(a,b,Vector::POL);
                }else{
                    cout << "input error\n";
                }
                break;
            }
            case 2:
            {
                cout << "Which model of ves do you want to see: ";
                cin >> mode;
                if(mode == rect){
                    cout << "use class function\n";
                    cout << vec.xval();
                    cout << std::endl;
                    cout << vec.yval();
                    cout <<"\nuse << ";
                    cout << Vector{vec.xval(),vec.yval(),Vector::RECT} << std::endl;
                }else if(mode == pol){
                    cout << "use class function\n";
                    cout << vec.magval();
                    cout << std::endl;
                    cout << vec.angval();
                    cout <<"\nuse << ";
                    cout << Vector{vec.magval(),vec.angval(),Vector::POL} << std::endl;
                }else{
                    cout << "input error\n";
                }
                break;
            }
            case 3:
            {
                cout << "Which mode: ";
                cin >> mode;
                if(mode == rect){
                    vec.rect_mode();
                }else if(mode == pol){
                    vec.polar_mode();
                }else{
                    cout << "input error\n";
                }
                break;
            }
            case 4:
            {
                Vector v1,v2;
                char op;
                cout << "Which mode: ";
                cin >> mode;
                if(mode == pol){
                    v1.polar_mode();
                    v2.polar_mode();
                }else if(mode != rect){
                    cout << "input error\n";
                    break;
                }
                cout << "Which op: ";
                cin >> op;
                if(op == '+'){
                    cin >> v1 >> v2;
                    cout << v1 + v2 << std::endl;
                }else if(op == '-'){
                    cin >> v1 >> v2;
                    cout << v1 - v2 << std::endl;
                }else if(op == '*'){
                    double n;
                    cin >> n;
                    cin >> v1;
                    cout << n << "*" << "vector =";
                    cout << n * v1 << std::endl;
                }
                break;
            }
            default :
                break;
        }
    }
    return 0;
}

总结

我们看到《C++ Primer Plus》中设计的vector类,其OPP编程思想无处不见

1.做好数据的隐藏,这里在主函数中的switch完全可以封装成一个函数,放在namespace VECTOR里

2.头文件尽量简洁,变量名函数名尽可能可做到见名知意,对于短小的类方法,可以写在头文件中,变成内联函数,可以提升程序效率

3.对于一个类,也尽量做到高聚合,低耦合,类方法间尽量不要冲突,拆成细小的function,进行不断组装。

4.函数要尽量短小精悍,不易过长,不同函数功能间的功能尽可能不要冲突。

5.关于代码风格,头文件中一类型的写在一起,中间用换行隔开,让代码看起来整齐,美观。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值