在C+中使用没有伙伴类/Cpp文件的头文件是否可行+; 我最近把C++作为我课程的一部分,我试图更深入地理解头和类之间的伙伴关系。从我查阅的每个示例或教程的头文件中,它们都使用一个带有构造函数的类文件,如果包含了方法,则使用方法。但是,我想知道,如果只使用头文件来保存一组相关函数,而不需要每次使用它们时都创建类的对象,是否可以 //main file #include <iostream> #include "Example.h" #include "Example2.h" int main() { //Example 1 Example a; //I have to create an object of the class first a.square(4); //Then I can call the function //Example 2 square(4); //I can call the function without the need of a constructor std::cin.get(); } //主文件 #包括 #包括“Example.h” #包括“示例2.h” int main() { //例1 示例a;//我必须首先创建类的对象 a、 square(4);//然后我可以调用函数 //例2 square(4);//我可以调用函数而不需要构造函数 std::cin.get(); }

在C+中使用没有伙伴类/Cpp文件的头文件是否可行+; 我最近把C++作为我课程的一部分,我试图更深入地理解头和类之间的伙伴关系。从我查阅的每个示例或教程的头文件中,它们都使用一个带有构造函数的类文件,如果包含了方法,则使用方法。但是,我想知道,如果只使用头文件来保存一组相关函数,而不需要每次使用它们时都创建类的对象,是否可以 //main file #include <iostream> #include "Example.h" #include "Example2.h" int main() { //Example 1 Example a; //I have to create an object of the class first a.square(4); //Then I can call the function //Example 2 square(4); //I can call the function without the need of a constructor std::cin.get(); } //主文件 #包括 #包括“Example.h” #包括“示例2.h” int main() { //例1 示例a;//我必须首先创建类的对象 a、 square(4);//然后我可以调用函数 //例2 square(4);//我可以调用函数而不需要构造函数 std::cin.get(); },c++,class,header,C++,Class,Header,在第一个示例中,我创建了一个对象,然后调用函数,我使用了两个文件“example.h”和“example.cpp” //Example1 cpp #include <iostream> #include "Example.h" void Example::square(int i) { i *= i; std::cout << i << std::endl; } //Example1 header class Exampl

在第一个示例中,我创建了一个对象,然后调用函数,我使用了两个文件“example.h”和“example.cpp”

  //Example1 cpp
    #include <iostream>
    #include "Example.h"

void Example::square(int i)
{
    i *= i;
    std::cout << i << std::endl;
}
//Example1 header
class Example
{
public:
    void square(int i);
};
//示例1 cpp
#包括
#包括“Example.h”
void示例::square(int i)
{
i*=i;

std::coutC++有一个单定义规则(ODR)。该规则规定函数和对象只应定义一次。问题是:标题通常包含多次。因此,您的
square(int)
函数可能会被定义两次

ODR不是绝对规则。如果将
square
声明为

//Example2 header
inline void square(int i)
// ^^^
{
    i *= i;
    std::cout << i;
}
//示例2标题
内联空心正方形(int i)
// ^^^
{
i*=i;

std::coutC++是一种多范式编程语言,它至少可以:

  • 程序(由条件和循环驱动)
  • 函数式(由递归和专门化驱动)
  • 面向对象
  • 声明性(提供编译时算法)
请参阅中的更多详细信息

面向对象范例(类)只是众多C++编程中的一个。 您可以将它们混合使用,也可以只使用一种或几种,这取决于您必须用软件解决的问题的最佳方法

因此,要回答您的问题:
是的,您可以在同一个头文件中组合一组(如果更好的话)相互关联的函数。这在“旧”C编程语言或更严格的过程语言中更常见

正如MSOLTES的回答所说,只要意识到C++的定义规则(ODR)。如果使用函数(体)的声明,而不仅仅是它的定义(模板豁免),则使用内联关键字。 请参阅此SO答案以了解对的描述

附加说明

执行答案,并将其扩展到C++中的其他编程范例, 最近几年,有一种趋势是将整个库(函数和/或类)放在单个头文件中。


这在开源项目中是常见的和公开的,只要转到GITHUB或GITLAB和

< P>当然,只有标题(只要考虑到已经提到的一个定义规则)就好了。

您也可以编写没有任何头文件的C++源。

严格地说,头不是别的,而是源代码,可能是<代码>包含了< /代码> d(即粘贴)到多个C++源文件(即翻译单元)。记住这个基本事实有时对我很有帮助。 我做了以下人为的反例:

main.cc

#include <iostream>

// define float
float aFloat = 123.0;

// make it extern
extern float aFloat;

/* This should be include from a header
 * but instead I prevent the pre-processor usage
 * and simply do it by myself.
 */
extern void printADouble();

int main()
{
  std::cout << "printADouble(): ";
  printADouble();
  std::cout << "\n"
    "Surprised? :-)\n";
  return 0;
}
/* This should be include from a header
 * but instead I prevent the pre-processor usage
 * and simply do it by myself.
 *
 * This is intentionally of wrong type
 * (to show how it can be done wrong).
 */

// use extern aFloat
extern double aFloat;

// make it extern
extern void printADouble();

void printADouble()
{
  std::cout << aFloat;
}
希望你已经注意到我宣布

  • main.cc中的外部浮动
  • printADouble.cc
这是一场灾难

编译
main.cc
时出现问题?否。翻译单元在语法和语义上是一致的(对于编译器)

编译
printADouble.cc
时出现问题?否。翻译单元在语法和语义上是一致的(对于编译器)

链接这些乱七八糟的东西时出现问题?没有。链接器可以解析所有需要的符号

输出:

printADouble():5.55042e-315
惊讶?:-)
正如预期的那样(假设你和我都没有预料到任何有意义的事情)

printADouble()
将定义的
float
变量(4个字节)访问为
double
变量(8个字节)。这是未定义的行为,在多个级别上出错

这样,使用头不支持,但启用(某种类型)C++中的模块化编程(直到我不得不使用C编译器(没有预处理器)之前,我才认识到它的区别。因此,上述草图问题对我来说非常困难,但对我来说也是非常有启发性的。”


总之,头文件是模块化编程基本功能的实用替代品(即明确定义接口,将接口和实现分离为语言功能)。这似乎也惹恼了其他人。请看一看我的意思。

常见的方法是并且一直都是将代码放在.cpp文件(或任何您喜欢的扩展名)中,并将声明放在标题中。 将代码放入头中有时也有一些好处,这可以让编译器进行更巧妙的内联。但同时,它会破坏编译时间,因为每次编译器包含代码时都必须处理所有代码

最后,当所有的代码都是标题时,循环对象关系(有时是需要的)通常是令人讨厌的

一些例外情况是模板。许多较新的“现代”库(如boost)大量使用模板,并且通常是“仅标题”库。但是,这只能在处理模板时进行,因为这是处理模板时的唯一方法。

只编写头代码的一些缺点 如果你四处搜索,你会看到很多人试图找到一种减少编译时间的方法
/* This should be include from a header
 * but instead I prevent the pre-processor usage
 * and simply do it by myself.
 *
 * This is intentionally of wrong type
 * (to show how it can be done wrong).
 */

// use extern aFloat
extern double aFloat;

// make it extern
extern void printADouble();

void printADouble()
{
  std::cout << aFloat;
}