从 C 中的类访问私有变量

新手上路,请多包涵

我正在做一个项目,我想在一个类中声明私有变量,因为我在很多地方都读到它比将它们声明为 public 更好,但是我如何在 main 中访问它们?我应该使用什么样的功能来使它们可以访问?我想通过一个不是像我所做的那样来自 main 的函数来解决系统问题。到目前为止,这是我的代码,

 #include <iostream>
#include <limits>

using namespace std;

class Equation
{
    private:
        int a1, a2, b1, b2, c1, c2;

    public:
};

int main()
{
    int a, b, c, d, e, f;
    cout << "\n" << endl;
    cout << "                        **** Hello ****               \n\n" << endl;
    cout << "This is a program to solve a system of equation" << endl;
    cout << "Equations will look like a1*x+b1*y=c1" << endl;
    cout << "and  a2*x+b2*y=c2\n" << endl;
    cout << "Enter the values for the first equation \n" << endl;

    while ((cout << "Enter the value of a1 :\n") && !(cin >> a))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    while ((cout << "Enter the value of a2 :\n") && !(cin >> b))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    while ((cout << "Enter the value of b1 :\n") && !(cin >> c))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    while ((cout << "Enter the value of b2 :\n") && !(cin >> d))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    while ((cout << "Enter the value of c1 :\n") && !(cin >> e))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    while ((cout << "Enter the value of c2 :\n") && !(cin >> f))
    {
        cout << "Invalid input, please enter a number \n" << endl;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }

    cout << "The first equation is : " << a << "x" <<
        "+" << c << "y" <<
        "=" << e << "\n" <<
        endl;

    cout << "The second equation is : " << b << "x" <<
        "+" << d << "y" <<
        "=" << f << "\n" <<
        endl;

    double x = ((c * e) - (b * f)) / ((a * e) - (b * d));
    double y = ((a * f) - (c * d)) / ((a * e) - (b * d));

    cout << "The solution of the system is " <<
        "x = " << x << "\t" <<
        "y = " << y <<
        "\n\n" <<endl;
    cout << "                        **** Thank You ****                 " << endl;

    return 0;
}

原文由 Germelinda Musliaj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 436
1 个回答

面向对象编程最强大的方面之一是具有封装性,即每个对象以自己的方式处理自己的数据。人们建议将变量声明为私有成员的原因是为了确保类始终处于有效状态。相信你的课程。赋予他们责任,处理他们自己的系统的权力。

另一个要点是关注点分离。基本上,如果您要执行的操作需要一个对象来更改其变量,则让对象处理该操作。实现这一点的方法是在类的公共部分声明一个函数,让您的客户(与您的类交互的任何代码) “请求” 该类进行更改并让您的类处理该更改。这是信任你的课程的第二步(我喜欢称之为 Empowering your classes )。是否需要使用您的类来更改数据?让你的班级去做。不要让其他实体通过命令你的班级来欺负你的班级。让他们问,不要乞求。

抛开所有的玩笑不谈, GettersSetters 是(可以说)这种方法令人作呕的副产品。从技术上讲,在您的班级中有这些符合面向对象编程的方案,因为您正在为您的客户提供一个接口来与您的数据进行交互。但是,它的工作方式与我们首先使用访问修饰符的原因背道而驰。这样的做法在计算机科学中通常被称为 anti-patterns ,这意味着它是一种变异的、危险的模式形式。我个人认为 Getters 并不那么糟糕,但 Setters 是各种讨厌的错误的根源。

RobClucas 的回答将是我要采取的方向。但不是通过构造函数发送数据,我还将输入读取功能带入 EquationSolver 类。这种方法似乎更类似于您最初计划做的事情,并且涉及的代码更改更少。

您的课程将是这样的:

 class EquationSolver {
public:
    void GetEquationParameters() {
        /* This is where your while(cin) blocks are
         You are reading information directly into this class' paramters
         while(cin>>a1)
         while(cin>>a2)
         etc..

        See how you're "asking" this class to read data from the user.
         */

        while ((cout << "Enter the value of a1 :\n")
            && !(cin >> a1)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        while ((cout << "Enter the value of a2 :\n")
            && !(cin >> a2)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        while ((cout << "Enter the value of b1 :\n")
            && !(cin >> b1)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        while ((cout << "Enter the value of b2 :\n")
            && !(cin >> b2)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        while ((cout << "Enter the value of c1 :\n")
            && !(cin >> c1)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        while ((cout << "Enter the value of c2 :\n")
            && !(cin >> c2)) {
            cout << "Invalid input, please enter a number \n" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }

    /*
     * Functions for your client to use to get the final data.
     * Former is the C++ style that returns both values as a pair.
     * Latter is the sweet sweet C style where you fill x and y inside the function.
     * Latter is less data transaction if you care about performance that much.
     */
    std::pair<double, double> SolveEquationSystem() const {
        double x = (b1*c1 - a2*c2) / (a1*c1 - a2*b2);
        double y = (a1*c2 - b1*b2) / (a1*c1 - a2*b2);

        return std::pair<double, double>(x, y);
    }
    void SolveEquationSystem(double * x, double * y) const {
        *x = (b1*c1 - a2*c2) / (a1*c1 - a2*b2);
        *y = (a1*c2 - b1*b2) / (a1*c1 - a2*b2);
    }

    /**
     * Human readable print
     */
    void PrintEquation() {
        cout << "The first equation is : " << a1 << "x" << "+" << b1 << "y" << "=" << c1 << "\n" << endl;
        cout << "The second equation is : " << a2 << "x" << "+" << b2 << "y" << "=" << c2 << "\n" << endl;
    }
private:
    int a1, a2, b1, b2, c1, c2;
};

在 main 函数中,这是你使用它的方式:

 void main() {
    cout << "\n" << endl;
    cout << "                        **** Hello ****               \n\n" << endl;
    cout << "This is a program to solve a system of equation" << endl;
        cout << "Equations will look like a1*x+b1*y=c1" << endl;
    cout << "and  a2*x+b2*y=c2\n" << endl;
    cout << "Enter the values for the first equation \n" << endl;

    // Create solver
    EquationSolver solver;

    // Ask solver to get parameters from the user
    solver.GetEquationParameters();
    // Ask solver to print equation in human readable format
    solver.PrintEquation();

    double x, y;
    // Ask solver to do what it's supposed to do
    solver.SolveEquationSystem(&x, &y);

    cout << "The solution of the system is " << "x = " << x << "\t" << "y = " << y << "\n\n" << endl;
    cout << "                        **** Thank You ****                 " << endl;

}

看看我是如何与班级互动的。作为客户 main ,我 要求 提供给我的课程以采取行动。我要求它获取将要使用 参数,然后要求它使用 它的 数据来解决系统问题。这样,如果出现错误,则与课程无关;这是我使用课程的方式。

旁注:尽量不要使用 using namespace std 。我知道学校教你使用它,但这只是你的老师懒惰。 using namespace x 将整个命名空间包含在头文件中,虽然对于小型项目来说没什么大不了的,但随着项目规模的扩大,它可能会导致一些严重的问题。

If you really want to get rid of std:: , say for cout and endl , then you can use using std::cout; and using std::endl; 而不是整个命名空间。不过,对于非特定功能,我仍然建议您使用 std:: (例如,我将其用于 std::numeric_limits 以指定我不是所有者,我是只是使用它)。

原文由 gamiseta 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题