2010-05-19 89 views
4

学习C++,看看奠定了这样的类:C++基本客舱布局

class CRectangle { 
    int x, y; 
    public: 
    void set_values (int,int); 
    int area() {return (x*y);} 
}; 

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

我知道Java和Java中的方法(函数)的类中写的。该类看起来像一个Java接口。我知道我可以这样写班级:

class CRectangle { 
    int x, y; 
    public: 
    void set_values (int a, int b) { 
     x = a; 
     y = b; 
    }; 
    int area() {return (x*y);} 
}; 

但是有差异还是标准?

回答

8

有区别。当您在类定义中写入函数的定义(情况2)时,则认为该函数已被声明为inline。这是标准的C++。

用法是在头文件(.h)中声明类定义内的成员函数(Java方法),并在C++文件中定义这些成员函数(.cpp,.cc或.C ,...)这会减少编译时间,当您更改函数的主体时,只需编译C++文件,而如果更改​​头文件中的某些内容,则将编译包含此头的所有C++文件。

4

通常的做法是将函数的实现放在一个单独的cpp文件中,这个文件不包含在其他文件中,只是编译完成。这样管理依赖关系就更容易了。

如果在类定义中给出了一个函数的实现(就像在你的第二个例子中一样),这是编译器对该函数进行内联的提示(最终可能会或可能不会这样做,具体取决于例如函数的内部)。作为一个经验法则,长于几行代码的函数体更好地放入cpp文件中,因为它们可能不会被内联,但是这些可能会包含额外的依赖性和混乱的类定义。

例外是模板函数,其中的主体也需要在标题中,因为编译器必须看到它们才能实例化模板。

1

我相信,如果方法体在类定义内部,那么它被内联到任何地方被调用。

+1

AFAIK这只是编译器的一个_hint_,它仍然可以自由决定该函数是否在最后被内联。 – 2010-05-19 08:56:56

+0

也许只有在头文件中定义类时才需要内联?或者,也许每个编译单元都得到它自己的代码副本,但只有一个? – 2010-05-19 10:37:12

5

如果您只在类定义(属于头文件)中定义原型并在cpp文件中实现这些方法,那就更简洁了。

当你有非常小的类来完成类定义中的所有内容听起来更容易,因为所有的东西都在同一个地方,但是只要你的类增长了,任何使用它的开发者都会恨你,因为他会让你的代码在方法原型,他可能会查找一些东西(不是每个人都使用IDE来显示所有可用的方法!)。

但是,有一个例外:模板类方法需要在标题中实现,因为它们需要针对模板的每个专业化进行编译。

+0

+1作为特殊情况提及模板。 – 2010-05-19 08:56:23

1

在C++中,在类中定义的成员函数隐含地是inline,在类外部定义的成员函数不是。

这会影响您的两个示例的关联 - 如果第一个示例在多个源文件中为#included,则链接器会抱怨多个定义,而第二个示例不会。

在一个什么样的标准/一般条款:

  • 第一种形式是用于复杂的类,其中的功能的实现需要额外的标头中拉
  • 第二种形式的用途。简单的类没有额外的依赖关系。
  • 基于开发人员的偏好,任一表单都用于模板类。
1

这里有一个细微的差别,这个类里面定义的函数自动地是inline。后一个定义可以放在一个单独的文件中。否则,没有区别或偏好。

请注意,我们通常不会在函数定义之后编写分号(尽管它们在类定义中是允许的)。

void set_values (int a, int b) { 
    x = a; 
    y = b; 
} // no semicolon here