C ++与类相关的标题

时间:2011-12-26 16:49:14

标签: c++ oop class header

我一直在阅读有关Header文件的不同文章和教程。 我理解Headers服务的目的是保持实现的“接口”。 (以及其他类似的编译优化)

我仍然没有得到,并且真的无法解开它,你总是使用标题吗? 我知道你可以在头文件本身中编写代码块。但那是我迷路的地方。

当我查看视频教程时,人们只需在Header文件中定义函数。然后另一篇文章只定义了函数(我猜这是接口的想法)。

目前我正在创建一个名为Color的简单类。 实现:

/* 
* File:   Color.cpp
* Author: Sidar
* 
* Created on 26 december 2011, 16:02
*/

#include <stdio.h>

#include "Color.h"

Color::Color() {

 reset();
}

Color::Color(const Color& orig) {

 a = orig.a;
 r = orig.r;
 g = orig.g;
 b = orig.b;
}

void Color::reset()
{
    a = 0;
    r = 0;
    g = 0;
    b = 0;
}

 Color::Color(unsigned int r, unsigned int g, unsigned int b, unsigned int a)
 {
   this->r = r;
   this->g = g;
   this->b = b;
   this->a = a;
 }

Color::~Color() {
   r = 0;
   g = 0;
   b = 0;
 }

 //getters____________________________
 unsigned int Color::getRed() const
 {
   return r;
 }

 unsigned int Color::getBlue() const
 {
   return b;
 }

 unsigned int Color::getGreen() const
 {
    return g;
 }

 unsigned int Color::getAlpha() const
 {
   return a;
 }

 //setters____________________________

 void Color::setRed(unsigned int r)
 {
   if(r > 255)r = 255;
   if(r < 0)r = 0;

   this->r = r;
}


void Color::setGreen(unsigned int g)
{
  if(g > 255)g = 255;
  if(g < 0)g = 0;

  this->g = g;
}

 void Color::setBlue(unsigned int b)
{
   if(b > 255)b = 255;
  if(b < 0)b = 0;

  this->b = b;
}

void Color::setAlpha(unsigned int a)
{
 if(a > 255)a = 255;
 if(a < 0)a = 0;

 this->a = a;
 }

 unsigned int Color::color()
 {
   return (int)a << 24 | (int)r << 16 | (int)g << 8 | (int)b << 0;
  }

这里是标题

/* 
 * File:   Color.h
 * Author: Sidar
 *
 * Created on 26 december 2011, 16:02
 */

 #ifndef COLOR_H
#define COLOR_H
#include <string>

class Color {
public:

    Color();
    Color(const Color& orig);
    Color(unsigned int r,unsigned int g,unsigned int b, unsigned int a);

    virtual ~Color();
    //____________________
    void setRed(unsigned int r);
    unsigned int getRed()const;
    //____________________  
    void setBlue(unsigned int b);
    unsigned int getBlue()const;
    //____________________
    void setGreen(unsigned int g);
    unsigned int getGreen()const;
    //____________________
    void setAlpha(unsigned int a);
    unsigned int getAlpha()const;
    //____________________
    unsigned int color();

   void reset();

private:

    unsigned int r;
    unsigned int b;
    unsigned int g;
    unsigned int a;


};

#endif  /* COLOR_H */

此代码确实有效,我没有收到任何错误。但这是header和cpp文件的一般概念吗? 我的第二个问题: 我读了很多,当使用模板时,我更容易在Header中实现代码我理解这一点(以防止许多实现被认为是如此通用的东西)。但是还有其他情况吗?

4 个答案:

答案 0 :(得分:4)

您并非“总是”做任何事情,这完全取决于您的团队或组织的环境,目标和编码标准。

C ++是一种非常灵活的语言,允许以多种不同的方式完成和组织事物。

可能会使用单独的实施文件:

  1. 将实现与界面分开,就像你一样 建议

  2. 加快编译时间

  3. 处理循环依赖

  4. 因此,您可以发送仅包含头文件的二进制库,而不是 基础源代码

  5. 您可能不需要单独的实施文件的一些原因:

    1. 您使用模板,“通常”必须使用模板定义 声明

    2. 您不希望将实现与接口分开。在 在许多情况下,这使得事情更容易理解,因为你没有 在标头和实现文件之间来回切换。这个 如果你正在处理大班,可能会适得其反 但是很多方法。

    3. 您希望尽可能多的代码由编译器内联 可能的。

    4. 您正在创建一个您不想要用户的代码库 不得不担心建设。大多数Boost库都是 这样,你就不必使用Boost构建系统了 可能是一件苦差事,但你只需要包含头文件 在你的代码中,你需要做的就是使用它们。


    5. 我通常通过定义头文件中的所有逻辑来开始新类的工作。然后当类完成时,或者当它开始变得拥挤在头文件中时,我将开始将逻辑移到单独的实现文件中。这完全是为了充分利用我的时间,因为当我可以在同一个文件中看到所有内容时,我能够更快地完成工作并减少错误。

      还应该注意,您根本不必使用头文件。您可以直接在.cpp文件中定义一些类。这通常是针对永远不会在.cpp文件之外使用的私有类完成的。

答案 1 :(得分:0)

好的,首先,这里是为什么模板只能在头文件中实现的答案:

Why can templates only be implemented in the header file?

这不是因为它是通用的,而是因为编译器实际处理模板的方式。如果你没有得到解释,请告诉我:)。

答案 2 :(得分:0)

如果将方法实现放在头文件中,C ++编译器可能会选择在调用站点内联代码。所以它可以更有效率。

如果你在一个头文件中完全定义了一个类,那么你就不需要一个.cpp文件来制作东西(如果实现很简单),那就更容易理解了。

答案 3 :(得分:0)

头文件不用于将“接口”与实现“分离”,它们已包含许多实现细节,除非您使用pimpl习惯用法。那是一个不同的主题,它可以用任何没有C#和Java等“头”文件的语言来完成。

它们的真正用途来自这样一个事实:当编译器必须为类的实例分配空间时,它必须知道它的大小。要计算大小,它需要该类的完整声明。由于您可能会在许多翻译单元中使用该类的实例,因此提供该声明的唯一理智方法是将其放在头文件中并在需要时#include它。

当您创建指向实例(或引用)的指针时,编译器不需要知道该类的大小,因为指针通常具有相同的4或8字节大小。对于这些情况,您可以使用前向声明而不是#including标头。

现在,您可以在头文件中包含代码的原因是由于当前的C ++模板机制。该代码将被编译多次,但编译器/链接器将消除所有副本并在最终编译的代码中保留一个副本。