我该怎么写课? C ++

时间:2011-02-17 21:35:20

标签: c++ oop class constructor destructor

嘿..我真的没有得到它们。我阅读了关于C ++中的类的教程,但我没有得到一些东西: 在我看过的每个示例和教程中,函数都不会写在类中!例如,为什么要编写这样的类:

#include <iostream>

using namespace std;

class test
{
    private:
        int x, y;
    public:
        test (int, int);
        int tester () {return x + y; }
};

test::test (int a, int b)
{
    x = a;
    y = b;
}

int main()
{
    test atest (3, 2);
    test atest2 (2, 6);

    cout << "test1: " << atest.tester() << endl;
    cout << "test2: " << atest2.tester() << endl;

    return 0;
}

或者像这样:

#include <iostream>

using namespace std;

class test
{
    private:
        int x, y;
    public:
        void set_values (int,int);
        int testfunc () {return x + y; }
};

void test::set_values (int a, int b)
{
    x = a;
    y = b;
}

int main()
{
    test tester;

    tester.set_values (3, 2);

    cout << "test1: " << tester.testfunc() << endl;

    return 0;
}

而不是像这样:

#include <iostream>

using namespace std;

class test
{
    public:
        int tester (int x, int y) { return x + y; }
};

int main()
{
    test atest;

    cout << atest.tester(3, 2) << endl;

    return 0;
}

老实说,我只是不明白!

为什么我需要私人会员?

何时以及如何使用析构函数?

我应该如何编写课程?

我在这里很困惑,我真的需要有人为我清理事情......谢谢

10 个答案:

答案 0 :(得分:3)

正如格雷格所说,你真的需要读一本书。

我应该如何写我的课程?
通过类,您可以将对其起作用的数据和函数组合成一件事。

为什么我需要私人会员? 私有成员只能通过类中的函数访问,这使您可以控制数据在类中的存储方式,而不会让类的用户能够执行您不期望的操作。

何时以及如何使用析构函数?
当您不再需要对象时,需要清理某些内容,关闭文件或释放内存。

答案 1 :(得分:2)

这个例子可以合理地分离出值的设置和检索,因为它们之间的数量比你在给定的main函数中看到的更多。如果没有,你完全正确,你应该将它们结合起来,甚至取消课程以支持免费功能。

例如,代码可能类似于:

void example(Test obj) {
  if (something) {
    process(obj.tester());
  }
}

int main() {
  int x, y;  // Imagine these are assigned to user input.
  Test obj (x, y);
  example(obj);  // Obj.tester may or may not be used.  If the x + y was not
  // separated, then you couldn't "maybe use" it.
  return 0;
}
  

为什么我需要私人会员?

你没有。他们的文档比其他任何东西都多。可访问性(公共/受保护/私有)是由编译器检查的文档。这种检查主要是为了封装值,但封装更多 而不仅仅是将某些东西标记为非公开的。例如,如果您(来自公共方法)返回对非公共数据成员的引用,那么您已将该成员的实现绑定到类的公共接口。

  

何时以及如何使用析构函数?

当你需要特殊的破坏逻辑时。阅读Rule of Three。将它们写成一个名为“〜”的类方法加上类名,不带参数并省略返回类型(甚至是void),类似于ctors。

  

我应该如何编写课程?

您不必在类之外定义方法。实际上,实现类中的所有方法开始,然后在需要时移出方法。当你学习语言的重要基础知识时,这很难搞砸,对于你最初编写的类的类型来说更方便。当ctor初始化器与ctor体内的赋值一样可行时,使用它们。

struct Test {
  Test(int x, int y)  // Use the same names rather than inventing 'a' and 'b'.
  : _x (x), _y (y)
  {}

  int tester() const { return _x + _y; }
  // Move outside the class when needed, if at all -- and it won't be needed
  // for a function like this.
  // Because this doesn't modify anything, it's suitable to be const, which
  // means it can be called on a const Test object.

  int _x, _y;
  // Technically public, but with a "non-public name".  Mark private as you
  // wish, or as the design settles down.
};

注意我使用“struct”来声明这个类而不是“class”。结果是相同的,除了我在任何基类上跳过“公共”(这里没有,但是基数通常是公共的而不是公共的),默认的成员可访问性也是“公共的”:这导致更短和更多明确的代码。

答案 2 :(得分:1)

私人成员隐藏了该类的内部,使其免于从外部操纵。这允许类的编写者更改内部实现细节而不必担心破坏其他代码,并允许类确保它保持有效状态。 (考虑一个腿长作为公共数据成员的三角形:没有办法阻止其他代码将腿长设置为2,3和7。)

析构函数通常应该释放对象持有的资源 - 例如文件句柄,数据库连接,堆上的内存块。如果对象没有这样的资源,通常不需要你编写析构函数。如果是这样,您可能还需要编写自己的复制构造函数和赋值运算符。 (可以使用“智能指针”来引用内存块,并且它们内置了自己的析构函数。)

你应该通过计算对象应该做什么来编写你的类。然后,编写允许调用者执行这些操作的函数声明。这为您提供了类的公共接口,因此这些函数应该是public:。然后,编写实现这些功能所需的一切。这几乎肯定会涉及数据,并且可能涉及公共职能部门将要调用的其他职能。这些事情应该是private:

通常,类定义进入头文件,头文件应尽可能少。较小的头文件意味着更快的整体编译时间(因为头文件将由#include d至少一个代码文件),并减少其他人,或者你六个月后,必须阅读以了解什么类确实。实现进入代码文件。

答案 3 :(得分:1)

  

为什么我需要私人会员?

私有成员允许您强制执行类不变量。假设您的课程代表一个银行帐户,您希望能够强制执行您的帐户中不会有负资金的想法。如果有任何代码可以修改帐户余额,则该课程无法保证。将帐户余额设为私有,然后该类可以保证该属性成立。

  

何时以及如何使用析构函数?

使用析构函数释放类所包含的资源,套接字,数据库连接和内存。需要注意的是三个规则。也就是说,如果你有一个非平凡的构造函数,你很可能需要一个析构函数和一个复制构造函数。

  

我应该如何编写课程?

课堂写作的一般指导方针将遵循SOLID原则。

答案 4 :(得分:1)

当你进入汽车的驾驶员座位时,你对如何操作汽车有一定的期望。向左转动车轮应将车辆转向左侧。踩油门踏板应使其行驶速度更快,按下踩下踏板应使其减速。作为驾驶员,您有权做出这些假设,因为世界已经标准化了您操作车辆的界面

那么,如果你驾驶的是电动汽车而不是内燃机汽车怎么办?车轮和/或踏板应该更换吗?当然不是!改变控制只是是愚蠢的,因为汽车的某些技术组件是不同的。无论汽车是由汽油,电力,水,仓鼠还是纯粹的动力供电都无关紧要;将车轮转向右侧应使汽车正确行驶!

在设计对象时,公共函数充当程序员的接口。程序员可以有一般假设,某些函数调用将产生某些类型的结果。继续汽车类比,良好的公共功能将是加速(),turnWheel(),toggleLights()等。糟糕的公共功能将是fuelInjection()。为什么驱动程序涉及操作该特定组件?汽车应该处理这些细节!好的私人成员将是fuelInjection(),exhaust()等。

一段时间后,汽车的比喻就会崩溃,所以让我们来看一个更实际的例子。假设您正在制作图像课程。您如何想象与良好的图像对象进行交互?喜欢这个?

Image i;
i.loadFromFile("myFace.jpg");

或者喜欢这个?

Image i;
i.preparePixelBuffer();
memset(i.pixelBuffer, 0, i.pixelBufferSize);
FILE* fp = fopen("myFace.jpg", "r");
bool doneLoading = false;
while (!doneLoading)
...

永远不要仅仅因为使用对象/类。想想你想要包含在课堂中的一个集中简洁的行为。它会让你的生活更轻松!

答案 5 :(得分:1)

  

我应该在类体中定义方法吗?   为什么我需要私人会员?

正如弗雷德所说,在学习,玩代码,甚至作为初选或其他情况的专业人士时,通常更容易做到这一点。一旦需要注意的具体事实是,类体定义是自动“内联”的,这意味着编译器在调用点插入代码并且可以避免函数调用开销。

将身体和私人成员分开方法的基本原则是encapsulation,或耦合/凝聚。这意味着使用该类的其他代码只对它声称要执行的操作(接口)感兴趣,而不是它是如何它(实现)。这在两个主要方面很有用:

  1. 在编写客户端代码时,我们可以更好地关注重要事项。
  2. 如果我们必须修复实现,我们很有可能不破坏客户端代码。
  3. 最后,所有这些归结为试图解决软件工程中如何将大型系统分解为组件以便具有可管理的代码库的问题。 C ++允许您使用类主体的公共部分和实现作为私有部分或.cpp文件来定义接口。这减少了系统中的整体耦合,从而降低了整体的复杂性。

      

    何时以及如何使用析构函数?

    封锁概念的一个例子是对象“拥有”资源。对象创建它的任何资源事物也负责释放。当对象被销毁时,因此需要释放剩余的资源。现在,经常对于简单的对象,你不需要明确做任何事情。 新程序员的主要情况是在使用'new'创建的对象上调用'delete'。避免使用smart pointers明确表达这一点很有用,例如std :: auto_ptr&lt;&gt;。

      

    我应该如何编写课程?

    绝对要确保您了解如何将代码拆分为.cpp文件。完成后,为了自学,你可以在课堂上使用代码。你可能会发现,班级的身体变得漫长而难以驾驭。这是一个迹象,它现在花时间将其拆分。分裂的另一个好例子是实现“有趣”。假设您有一个使用OpenGl实现的绘图类。将详细信息放在.cpp文件中意味着其余代码不会包含OpenGl头文件。

答案 6 :(得分:0)

传统上,类定义中定义的方法是内联的。也就是说,执行时不会进行任何调用。但是,对于较新的编译器,有关内联的规则更复杂。但是,我认为一个好的经验法则仍然是在标题中定义你想要内联的方法。

您不需要私人会员。类提供了一种将代码组织到逻辑单元的方法。通过将成员设为私有,您可以将该逻辑封装在您的类中。这样做的好处是,您可以专注于这些私有成员,而无需担心应用程序的其他部分所做的事情,因为应用程序的其他任何部分都不会直接访问这些成员。

答案 7 :(得分:0)

如上所示,第一种写入方式允许您将函数定义(您的类接口)分离为头文件,将函数声明(您的类实现)分离到.cpp文件中。您可以在this question中了解有关头文件的更多信息。 inlining某些方法有一些好处,你可以这样做的方法是在类中编写函数声明,但为了获得这些好处,你的方法必须符合几个标准。

私有成员允许您隐藏类的数据,以便只有该类可以操作该数据。它提供了一种处理正确encapsulation和重要的面向对象编程概念的方法。封装将对某些数据进行操作的所有方法捆绑到一个单独的类中,这可能有助于在软件中实现漂亮,清晰的设计。

this question中有更多关于析构函数的内容。如果您对C ++析构函数感到困惑,您可能希望在一本优秀的C ++书籍(如Accelerated C ++)中阅读C ++中的内存。

答案 8 :(得分:0)

你实际上还需要学习更多! 让我们从成员开始 私有成员意味着您可以访问它,阅读它,以任何方式更改它只能使用该类 受保护的成员意味着相同,但您也可以通过继承访问它(稍后读取继承) 公共意味着......好吧,你可以从任何你想要的东西访问它。 在小型程序中,这并不重要,但如果你是一个拥有10或100名程序员的团队,你可能希望保留一些东西,而不能改变你想要的一切。

分类以这种方式编写,因为这是C ++的方式,事实是你定义类的部分 - &gt; class square {};是阶级的堕落。你设计你的类并定义类成员。然后在编译器知道哪个成员属于哪个类然后它进入实际的成员并使用实际成员时,如果你在程序中使用.h文件,那么你将更好地理解 标题是您设计碰撞的地方,然后是包含.h的cpp,您实际上是在实现变量的方法和值

最好的部分是析构函数。当类的实例被删除时,您需要析构函数来删除对象。删除对象是编程的一部分,需要在内存分配和释放方面有很好的基础。 我必须推荐一本帮我很多的书 书:“用C ++思考” 我的建议是,无论如何都要保持编码!如果你试图找到一些例子,如果你仍然无法解决问题,请休息一下再试一次

享受!

答案 9 :(得分:0)

很多人都说你需要把你的班级分成.h文件和.cpp文件。这通常由业余爱好程序员完成,因为当你回顾它们看他们做什么时,它有助于使大型课程的谈判变得更小。拥有使该类实际与您可以使用的所有函数/数据成员在同一文件中工作的所有代码,使得很难看到如何实际“使用”该类。

基本上,它可以让你只看完头文件,并忘记这个类实际上是如何工作的!至少,这是目标。当你进入专业编程,或者只是真正的大项目时,它也有助于编译时间,将它的工作方式与那些不需要打扰它的代码的人分开等等。

私人成员主要是为了保护你未来的自我免受过去的自我。所以......比如说,你写了一个类,它有一个方法可以返回一个员工有多少钱。

int Employee::GetDollars(int employee_id); 
你打电话给它。所有这一切都返回了类中的私有'int dollars []'数据变量,可能是'return dollars [employee_id];'现在将来,如果你改变了如何确定哪个employee_id得到哪个员工或其他什么,你只需要在一个地方改变它。而不是你刚刚使用了classname.dollars [id],因为那时你必须在你曾经使用过的程序中的每一个点都改变它!