首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单行输入跟踪计算器

单行输入跟踪计算器
EN

Code Review用户
提问于 2015-01-20 12:52:54
回答 1查看 1.7K关注 0票数 3

问题的第二部分。我已经重写了代码的大部分部分,希望这样做会更好。代码现在有一些更多的逻辑和较少的可读性。

计算器中包含的

函数:

  • 添加用户输入2+2程序输出4
  • 减法用户输入2-2程序输出0
  • 乘法用户输入2*2程序输出4
  • 除法用户输入2/2程序输出1
  • 指数用户输入2^2程序输出4
代码语言:javascript
复制
#include <iostream>
#include <string>
#include <sstream>
#include <Windows.h>
#include <cmath>

class Math_Functions
{
public:
    double addition(double, double);
    double subtraction(double, double);
    double multiplication(double, double);
    void division(double, double);
    void exponentiation(double, double);
} math;

class Results_Handler
{
public:
    void division(std::string);
    void exponentiation(std::string);
} res_handler;

//This function I found somewhere in the deep internet
class Miscellaneous
{
public:
    void Pause()
    {
        std::cout << std::endl << "Press any key to continue . . . ";
        std::cin.sync();
        std::cin.ignore();
    }
    void ClearScreen()
    {
        HANDLE                     hStdOut;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        DWORD                      count;
        DWORD                      cellCount;
        COORD                      homeCoords = { 0, 0 };

        hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
        if (hStdOut == INVALID_HANDLE_VALUE) return;

        /* Get the number of cells in the current buffer */
        if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
        cellCount = csbi.dwSize.X *csbi.dwSize.Y;

        /* Fill the entire buffer with spaces */
        if (!FillConsoleOutputCharacter(
            hStdOut,
            (TCHAR) ' ',
            cellCount,
            homeCoords,
            &count
            )) return;

        /* Fill the entire buffer with the current colors and attributes */
        if (!FillConsoleOutputAttribute(
            hStdOut,
            csbi.wAttributes,
            cellCount,
            homeCoords,
            &count
            )) return;

        /* Move the cursor home */
        SetConsoleCursorPosition(hStdOut, homeCoords);
    }
} misc;


//Handle the result from division and cout correspondingly
void Results_Handler::division(std::string inPut)
{
    if (inPut != "Error")
    {
        std::cout << inPut;
    }
    else
    {
        std::cout << "Come on, you know you can't divide by 0...";
    }
}

//Handle the result from the exponentiation and cout correspondingly
void Results_Handler::exponentiation(std::string inPut)
{
    if (inPut != "Error")
    {
        std::cout << inPut;
    }
    else
    {
        std::cout << "You can't exponentiate by negative numbers.";
    }
}

double Math_Functions::addition(double a, double b)
{
    return a + b;
}

double Math_Functions::subtraction(double a, double b)
{
    return a - b;
}

double Math_Functions::multiplication(double a, double b)
{
    return a * b;
}

void Math_Functions::division(double a, double b)
{
    //Dividing by 0 = universe explodes
    if (b == 0)
    {
        res_handler.division("Error");
    }
    else
    {
        double c = a / b;
        std::stringstream result;
        result << c;
        res_handler.division(result.str());
    }
}

void Math_Functions::exponentiation(double a, double b)
{
    //If the number you're exponentiating with is 0 the result is always 1
    if (b == 0)
    {
        res_handler.exponentiation("1");
    }
    //If you're exponentiating with 1 the result is the same number
    else if (b == 1)
    {
        std::stringstream res;
        res << a;
        res_handler.exponentiation(res.str());
    }
    else
    {
        std::stringstream res;
        res << pow(a, b);
        res_handler.exponentiation(res.str());
    }
}

int main()
{
    //Declare variables
    double a, b;
    char function;
    std::string line;

    while (true)
    {
        misc.ClearScreen();
        std::getline(std::cin, line);

        //Check if the input is empty and ignore
        if (line.empty())
        {
            continue;
        }
        //Check if the input is either 'q' or 'Q' and break loop
        else if (line[0] == 'q' || line[0] == 'Q')
        {
            break;
        }
        //Else if everything is OK extract data
        else
        {
            std::istringstream inStream(line);
            inStream >> a;
            inStream >> function;
            inStream >> b;

            //Check for bad input and print error
            if (!inStream || function != '+' && function != '-' && function != '*' &&     function != '/' && function != '^')
            {
                std::cerr << "\"" << line << "\" is invalid input";
            }
        }

        //Check what the user wants to do
        switch (function)
        {
        case '+': std::cout << math.addition(a, b); break;
        case '-': std::cout << math.subtraction(a, b); break;
        case '*': std::cout << math.multiplication(a, b); break;
        case '/': math.division(a, b); break;
        case '^': math.exponentiation(a, b); break;
        }
        misc.Pause();
    }
    return 0;
}
EN

回答 1

Code Review用户

发布于 2015-01-20 17:07:48

单例模式:

您的类Math_FunctionsResults_HandlerMiscellaneous似乎是对单例模式的尝试(参见12)。声明每个类的全局实例的方法也是有效的,但是有一些缺点,而且不是很传统。

由于您的类不包含任何成员数据,而且这个类实际上只是函数的名称空间,所以我将使用一个实际的namespace,在这种情况下甚至不用考虑完整的单例实现。示例:

代码语言:javascript
复制
namespace math
{
    double addition(double, double);
    double subtraction(double, double);
    double multiplication(double, double);
    void division(double, double);
    void exponentiation(double, double);
} // namespace

然后,要访问每个函数,现在必须使用:: (命名空间解析)运算符:math::addition(a, b);

杂项提示:

  • 将参数名称保存在函数原型中。这将添加到代码文档中。
  • 与你的命名约定保持一致。函数/方法有PascalCasecamelCase名称。选择一个并始终如一地使用。
  • 应该使用带有<cmath>前缀的完全限定名来访问pow()等来自std::的函数。即:std::pow().
  • 考虑将项目拆分为几个单独的源文件。这里已经有相当多的代码要保存在同一个源文件中。理想情况下,应该将每个类放在自己的.cpp/.h对中。
  • main末尾返回零是可选的。如果不显式执行,编译器将默认为return 0
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/78115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档