繁体   English   中英

C ++(OOP)中的类和封装

[英]Classes and encapsulation in C++ (OOP)

我们正在使用OOP在我的课程中进行CPP课程,而且我有点迷失了他们。 我理解整个过程 - 我想,但我似乎无法做到正确。 我是新手,所以请放轻松我。

基本上,这个分配任务的整个前提是创建以下变量和类:

  1. 创建一个名为Triangle的类
  2. 封装a,b,c - 三角形边长
  3. bool Set(双aa,双bb,双cc); - 设置值并返回true或false,具体取决于是否可以使用基于这些长度的三角形
  4. 双Perim(); - 计算三角形的周长。
  5. 双面积(); - 计算三角形区域。
  6. bool isRect(); - 检查这是否是一个直角三角形。

我希望这是有道理的?

以下是我到目前为止的情况:

main.cpp文件(远非完整,此刻就像占位符一样):

#include <iostream>
#include "triangle.h"

using namespace std;


int main() {
  Triangle t;
  int aa, bb, cc;

  cout <<"Triangle side 1 - " <<endl;
  cin >> aa <<endl;
  cout <<"Triangle side 2 - ";
  cin >> bb <<endl;
  cout <<"Triangle side 3 - ";
  cin >> cc <<endl;


return 0;
}

Triangle.h文件:

#include <iostream>
#include "Triangle.cpp"

using namespace std;

#ifndef TRIANGLE_H
#define TRIANGLE_H

class Triangle(){

private:
  double a;
  double b;
  double c;

  double Perim();
  double Area();
  bool IsRect();

public:
  Triangle();
  Triangle(int, int, int);
  bool set(double aa, double bb, double cc);
};

#endif

和Triangle.cpp文件(用公式计算一切)

#include "Triangle.h"

  Triangle::Triangle(){
   a = b = c = 0;
   Perim = 0.0;
   Area = 0.0;
 }

 Triangle::Triangle(int aa, int bb, int cc){

 }

  double Triangle::Perim(){
    return a + b + c;
  }

  double Triangle::Area(){
    s = (a+b+c)/2;
    Area = SQRT(s(s-a)(s-b)(s-c));
    return Area;
  }

  bool Triangle::isRect(){
    return (((a*a) + (b*b)) == (c*c)) ? true : false; //---checks if this is a right angle triangle, and should return true or false.
  }

  bool Triangle::Set(double aa, double bb, double cc){
    a = aa;
    b = bb;
    c = cc;

        if (a + b > c && a + c > b && b + c > a){//if one of these criteria is false, then a triangle is not possible.
          return cout << "A triangle with these parameters is possible.";
        }
        else{
          return cout << "A triangle with these parameters is NOT possible.";
        }
}

当然,这远非完整,但我努力将所有事物联系在一起。 我试图获取Main.cpp文件,当人输入值时,应该传递给其他cpp文件并进行计算,并且一旦完成,就通过对象(尚未创建)将值返回到Main cpp。 如果这有道理?

我一直试图绕过这几个小时,我似乎无法把它弄好,希望有人在这里指出我正确的方向?

提前谢谢你,对于凌乱的代码感到抱歉..

这是一个可以接受的开始。 但这里有几个问题。

我们先来看看标题:

你需要摆脱cpp文件的#include 您应该只在标头中包含标头。 最好将自己限制在标题中代码所需的标题中。 例如,类定义并不真正需要<iostream> 因此将此包含移动到需要它的cpp。

你还需要摆脱using子句:这应该在cpp中使用,而不是在头文件中使用,因为它会导致包含头文件的文件忽略导入另一个命名空间,这可能会在以后创建冲突(在较大的项目中) 。 有关如何在此处使用标头的更多建议。

然后Triangle是一个类而不是一个函数。 所以你必须用class Triangle { ... };定义它class Triangle { ... }; 而不是class Triangle() {...};

我还希望以下成员函数是公开的:

double Perim();    // These are definitively of interest for users of Triangles
double Area();
bool IsRect(); 

现在来实施

首先,您需要避免成员变量和成员函数之间的混淆:

  Triangle::Triangle(){
   a = b = c = 0;
   // Perim = 0.0;   // NO !! Perim() is a function, you cannot assign a value to it
   // Area = 0.0;
 }

然后你需要声明你使用的变量:

 double Triangle::Area(){
    auto s = (a+b+c)/2;                // because s deosn't exist
    return std::sqrt(s*(s-a)*(s-b)*(s-c));   // sqrt requires include <cmaths>
                                       // multiplication must be explicit.  
  }

然后你可以返回一个布尔表达式。 无需更明确:

bool Triangle::isRect(){
    return ((a*a) + (b*b)) == (c*c); 
  }

最后,你的set函数需要一些返工:你必须返回truefalse 你最好不要在return语句中使用cout ,但在返回之前。 最后但并非最不重要,您必须在分配成员变量之前执行有效性测试。

最后到main()

输入和输出流是不同的东西。 所以不要尝试<<endl on cin!

输入工作后,您可以使用t.set(...)来使用用户输入的值来更改t。

如果t.set(...)返回true,则可以显示函数的结果。 例如:

 cout << "Area: " << t.Area()<<endl; 

如果结果为假,则更好地告知用户您不能再使用这样的三角形。

我想你知道编译如何编译main.cpp和triangle.cpp。

1)包括头文件,而不是cpp文件!

去掉:

    #include "Triangle.cpp"

原因:

cpp文件是编译的。 它们依赖于头文件,而不是相反。 标头可以依赖于其他标头,这实际上发生了很多。 但他们不应该依赖于cpp文件。

2)在ifndef / define块中包装头。

移动:

#ifndef TRIANGLE_H#define TRIANGLE_H到文件的顶部,高于其他所有内容。 在风格上你可能想要评论文件在ifndef / define块上面而不是在下面的内容

例:

    // This is the triangle header file! Here is where I describe it.
    #ifndef TRIANGLE_H
    #define TRIANGLE_H
    // TODO: Put the includes here
    // TODO: Put your class here
    #endif

原因:

在C ++中,您可以想到以下行: #include <iostream>将iostream文件的内容复制粘贴到该行的上方。 因此,当您在main.cpp和triangle.cpp中#include“triangle.h”时,您将描述三角形类对每个cpp文件的外观。 main.cpp需要知道它可以创建和使用三角形,而triangle.cpp需要知道它才能正确实现Triangle中的函数。

如果您包含两次文件,则该文件将被有效地复制粘贴两次。 通常,这将重新定义其内容,这将是编译错误。 ifndef / define块的作用是“嘿,如果尚未定义TRIANGLE_H,这是它第一次被包含。所以继续定义TRIANGLE_H,以及所有文件内容。下一次triangle.h是包括我们将看到TRIANGLE_H已经定义,我们跳过该标题的内容,而不是重新定义Trinagle是什么。

我建议你把它移到顶部的原因是你包括iostream,triangle.cpp(我们已经讨论过那个部分)并且每次包含triangle.h时都使用命名空间std。 没有必要这样做。

3)修复三角类声明

更改:

    class Triangle(){

    class Triangle {

原因:

你很亲密! 但是你混淆了使用声明一个类的语法来声明构造函数的语法。

4)使您打算在Triangle公共之外使用的功能。

移动:

double Perim();上面的“public:”访问说明符double Perim();

原因:

如果你想调用方法:来自main.cpp的Perim,Area和IsRect(或者来自anywehre但三角形类的内部!)你需要将这些方法公开。

你可能想把所有东西都公之于众,但这种形式很糟糕 - 你的导师专门说“封装a,b,c”。 您可以谷歌封装设计模式来了解原因。 我不会在这里介绍它。

5)填写三角形构造函数

看方法:

    Triangle::Triangle(int aa, int bb, int cc)

变化:

  • 在头文件中,您不提供三个参数名称。 这不是一个错误,但它很奇怪。 您应该给出这些参数名称。

  • 在你的另一个构造函数(没有参数的构造函数)中,你表明你知道如何分配a,b和ca值! 继续并在此方法中为它们分配值。

  • 考虑一下你是否真的想使用int作为参数的类型。 您将边长存储为双精度,但是您将它们作为整数提供给构造函数。 这不是一个错误,但它很奇怪。

6)修复Set方法的主体。

看方法:

    Triangle::Set(double aa, double bb, double cc)

注意:

记住一种方法是交换。 你提供它的参数,它做了一些工作,它返回给你一些价值(除非它'返回'无效)。 你的方法是要求3个双打,并返回一个布尔。 如果你要归还一个布尔,你就同意给出一个真值或假值。 在这里,你要回报任何cout <<“......”; 回报。 这听起来不像你想要的(即使它编译)。 你不关心cout什么回来,对吧?

变化:

不要在这个功能上做任何事情。 如果三角形可能则返回true,如果不可能则返回false。 你可以从调用Set的地方cout你想要的任何东西。

7)封装a,b,c。

你把ab和c私有化了。 这是封装的一半。 您的教师可能希望您在Triangle中为这些变量编写一个getter和setter。

例:

    double Triangle::GetA() {
        return a;
    }

    void Triangle::SetA(double aa) {
        a = aa;
    }

我会把它留作exersize来做其余的事情。

8)在main.cpp中使用你的三角形

如果你使用局部变量t ,你可以像这样调用函数:

    t.SetA(1.1);
    cout << t.GetA() << endl; // will print 1.1

    double theValueOfA; // local variable
    theValueOfA = t.GetA(); // store the result of GetA in our new variable

    cout << theValueOfA << endl; // will also print 1.1

有了这些信息,在您完成对cin的调用以获取用户输入后,请执行以下操作:

  • 创建一个布尔变量来存储set的结果,稍后我们将使用它。
  • 在t上调用Set函数,提供用户输入的3个长度。 在我们的布尔值中存储Set的返回值。
  • 写一个if语句。 检查该布尔值是否为true。 如果是,则打印“可以使用具有这些参数的三角形。”,否则打印“不能使用具有这些参数的三角形”。
  • 如果你的作业要求你做任何其他或不同的事情,比如打印Perim,Area和isRect的结果,那就去做吧!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM