将笛卡尔点存储在矢量和输出距离中

Storing Cartesian points in a vector and outputting distance

本文关键字:输出 距离 笛卡尔 存储      更新时间:2023-10-16

我很难为我创建的课程编写我的主体。我创建了一个名为CartesianPoints的类,我想用它来构建自己的主体。我拥有我的主要创建的一般结构,但正在与一些技术人员挣扎。

我要寻找的东西:

  • 创建一个cartesianpoint对象的空矢量,这将是向量的起点
  • x和y值的极限范围在10&amp之间;-10。
  • 向用户向用户展示他们刚输入的要点,并询问他们想输入什么
  • 上面的环应继续直到触发休息

这是我的Cartesianpoints的标题

    #ifndef MY_CARTESIAN_POINT_H
    #define MY_CARTESIAN_POINT_H
    #include <iostream>         // cin, cout
    #include <sstream>          // stringstream
    #include <cmath>            // sqrt()
    #include <limits>           // INT_MAX
    #include <stdexcept>        // out_of_range
    using namespace std;

    class CartesianPoint
    {
      public:
        CartesianPoint(int x = 1, int y = 1) { SetPoint(x, y); }

        int GetX() const { return myX; }
        int GetY() const { return myY; } 

        double GetDistanceTo(CartesianPoint pointTo) const; 
        string ToString() const;    

        void SetX(int x) { myX = validateCoordinateValue(x); } 
        void SetY(int y) { myY = validateCoordinateValue(y); } 
        void SetPoint(int x, int y) { SetX(x); SetY(y); }   
        static int GetLimit() { return sharedLimit; }
        static void SetLimit(int limit) { sharedLimit = abs(limit); }
      private: 
        int myX; 
        int myY;  

        static int sharedLimit; 

        int validateCoordinateValue(int value) const;
    };  
    int CartesianPoint::sharedLimit = INT_MAX;    
    double CartesianPoint::GetDistanceTo(CartesianPoint pointTo) const 
    {
        int xDelta = pointTo.myX - myX; 
        int yDelta = pointTo.myY - myY;
        return sqrt((xDelta * xDelta) + (yDelta * yDelta));
    } 
    string CartesianPoint::ToString() const
    {
        stringstream strOut; 
        strOut << "(" << myX << ", " << myY << ")";
        return strOut.str();
    }
    int CartesianPoint::validateCoordinateValue(int value) const
    {
        if((value < -sharedLimit || value > sharedLimit))
        {
            throw out_of_range( "Parameter (" + to_string(value) + ") must be between " 
                + to_string(-sharedLimit) + " and " + to_string(sharedLimit) + ".");
        }
        return value;
    }
    #endif

这是我到目前为止的主要人物

int main()
{
GreetingScreen(); // just a formatting function ive already created 
// while loop that makes will give the option to end the program.
while(/* if myX! =10 and myY!= 10 keep doing this loop */ )
{
    // try catch for errors....
    try
    {
        cout << "Move from point"  /* (0,0)*/ "to where?" << endl;  
        cout << "X: " << endl;
        cin >> x; //point x 
        cout << "Y: " << endl; 
        cin >> y; //point y 

        catch 
        {
            cerr << "could not do this task"; 
        }
    } 
} // ending of while loop 
} // ending of main 

您走在正确的路径上,但是我确实看到了一些事情。

  • 在您的班级中,我看不到您在哪里使用<iostream>,我认为您可以省略它。

  • 您正在使用using namespace std。首选仅范围内命名空间std::

  • 关于您的构造函数:

    CartesianPoint(int x = 1, int y = 1) { SetPoint(x, y); }
    

在这里您有两个默认值,这里有两个选项:

  • 将此构造函数声明为 explicit

    explicit CartesianPoint( int x = 1, int y = 1 ) { SetPoint( x, y ); }
    
  • 声明默认和用户定义的构造函数

    CartesianPoint() { SetPoint( x, y ); }
    CartesianPoint( int x, int y ) { SetPoint( x, y ); } // by value
    CartesianPoint( int& x, int& y ) { SetPoint( x, y ); } // by reference
    

note - 第三个构造函数我的要求过载设定点功能要通过参考接受,但是,如果您继续阅读下面的读数,您将看到我对您的班级所做的一切。

我个人认为2 nd 选择是两者中的更好。如果您选择使用带有2个参数的构造函数,并且两个都有默认值,并且您不会将构造函数声明为明确;您会遇到麻烦。

这就是为什么我最好选择使用2 nd 声明默认构造函数和用户定义的构造函数的选项。这使您可以灵活地执行以下任何操作:

{
     CartesianPoint p1;  // default constructor called
     CartesianPoint p2( 5, 6 ); // user defined constructor called.
     int x = 5;
     int y = 6;
     CartesianPoint p3( x, y ); // another user defined constructor called.
}

现在,构造函数还有其他内容:您正在调用成员函数来设置点(x,y)这不是真正需要的。班级的成员初始化列表;使用它们!您还使用成员函数SetX()SetY()在您的成员函数SetPoint()中不需要额外的呼叫。


我个人会写你的班级:

#ifndef MY_CARTESIAN_POINT_H
#define MY_CARTESIAN_POINT_H
// #include <iostream>      // cin, cout
#include <sstream>          // stringstream
#include <cmath>            // sqrt()
#include <limits>           // INT_MAX
#include <stdexcept>        // out_of_range
// using namespace std;
class CartesianPoint {
private:
    int myX;
    int myY;
    static int sharedLimit;
public:
    CartesianPoint() : myX( 0 ), myY( 0 ) {} // I chose 0, but you can choose any default values for (x,y)
    CartesianPoint( int x, int y ) : 
        myX( validate( x ) ), 
        myY( validate( y ) ) {
    }
    CartesianPoint( int& x, int& y ) :
        myX( validate( x ) ),
        myY( validate( y ) ) {
    }
    int GetX() const { return myX; }
    int GetY() const { return myY; } 
    // by value
    void SetX(int x) { myX = validate(x); } 
    void SetY(int y) { myY = validate(y); } 
    void SetPoint(int x, int y) { 
        myX = validate( x );
        myY = validate( y );
    }
    // by reference
    void SetX( int& x ) { myX = validate(x); }
    void SetY( int& y ) { myX = validate(y); }
    void SetPoint( int& x, int& y ) {
        myX = validate( x );
        myY = validate( y );
    }
    double GetDistanceTo(CartesianPoint pointTo) const; 
    string ToString() const;
    static int GetLimit() { return sharedLimit; }
    static void SetLimit(int limit) { sharedLimit = abs(limit); }
  private:
    int validate( int value ) const;   // by value
    int validate( int& value ) const;  // by reference
};  
int CartesianPoint::sharedLimit = INT_MAX;    
double CartesianPoint::GetDistanceTo(CartesianPoint& pointTo) const  {
    int xDelta = pointTo.myX - myX; 
    int yDelta = pointTo.myY - myY;
    return sqrt((xDelta * xDelta) + (yDelta * yDelta));
} 
std::string CartesianPoint::ToString() const {
    std::stringstream strOut;
    strOut << "(" << myX << ", " << myY << ")";
    return strOut.str();
}
int CartesianPoint::validate(int value) const {
    return validate( value );
}
int CartesianPoint::validate( int& value ) const {
    if((value < -sharedLimit || value > sharedLimit)) {
        std::ostringstream stream;
        stream << "Out Of Range: Parameter (" 
               << + ToString(value) 
               << + ") must be between " 
               << + ToString(-sharedLimit) 
               << + " and " 
               << + ToString(sharedLimit) 
               << + '.';                
        throw stream.str();
    }
    return value;
}

#endif

main.cpp

#include <iostream>   
#include "CartesianPoint.h"
int main() {
    try {
        std::vector<CartesianPoint> points; // It's already empty
        while( condition(s) ) {
            // do work
        }
    } catch( std::string& str ) {
        std::cout << str << std::endl;
        return -1;          
    } catch( ... ) {
        std::cout << "Caught some other or unknown exception." << std::endl;
        return -1;
    }
    return 0;
}

edit - 我对validateCoordinateValue进行了更改,我首先将其名称更改为validate,原因是:

  • 1 st :它是该功能的一种私人方法,并且不会作为其公共界面的一部分暴露。
  • 2 nd :它较短,更易于键入和读取。
  • 3 rd :在班级中使用它时,就像validate()一样,它已经自我解释了该函数的作用。比较两者:
    • myX = validateCoordinateValue( x );
    • myX = validate( x );

然后,我还添加了该函数的超载,以通过参考接受通过。参考版本可以完成工作,按值函数通过,只需返回并调用参考版本。