C++ 为什么extern“;C”;C组和x2B组+;类(不是标题)在这里?

C++ 为什么extern“;C”;C组和x2B组+;类(不是标题)在这里?,c++,linkage,C++,Linkage,我在搜索SVM库时遇到了一个问题 在源代码中,我发现了一个不寻常的用法,如下所示: #sample.h #ifndef SAMPLE_H #define SAMPLE_H //no header included or namespace declared here #ifdef __cplusplus extern "C" { #endif //no header included or namespace declared too class Sample: public Pare

我在搜索SVM库时遇到了一个问题

在源代码中,我发现了一个不寻常的用法,如下所示:

#sample.h

#ifndef SAMPLE_H
#define SAMPLE_H

//no header included or namespace declared here

#ifdef __cplusplus
extern "C" {
#endif

//no header included or namespace declared too

class Sample: public Parent
{
public:
    Sample();
    ~Sample();

    type0 fun(type1 val1, type2 val2);
    ...
};

#ifdef __cplusplus
}
#endif

#endif // SAMPLE_H
int blah(double num);
如图所示,头中不需要额外的头或名称空间,它们都在cpp文件中

以下是我的想法:

<>为什么 Exc“C”/COD>,通常用于C接口,将C++类分组?这种用法对某些东西有用吗

  • 即使出现了
    type0
    type1
    type2
    ,它们自己的标题也不包括在这里,而是包含在cpp文件中(例如sample.h)。然而,当我调用类
    Sample
    时,我必须包含这些标题(例如
    type0.h
    type1.h
    type2.h
    ),这似乎不方便

  • 根据C语言,在确定类成员名称的语言链接和类成员函数的函数类型时忽略了语言链接

    因此,这种分组看起来毫无意义,除非
    type0
    type1
    type2
    是内联定义的函数指针,在这种情况下,它们将具有C链接

    如果
    type0
    type1
    type2
    是用户定义的类型,并且它们的定义放在单独的标题中,这违反了良好的C/C++风格规则-所有标题都应是自包含的,并且不需要额外的编译内容

    为了回答主要问题(‘为什么?’)-看起来C语言链接只是从另一个标题(可能是纯C,这是有意义的)盲目复制粘贴的。
    或者它可能是故意做的——因为“一致性”的原因。

    从C的角度来看,有多种原因可以这样做(你的问题2)。一个是数据隐藏,另一个是通过减少包含层次结构来提高编译时间

    C允许使用类型指针(将它们传递给函数等),而不知道它们/包括它们。除非你取消引用,否则没关系。因此,将处理结构细节留给实现者函数,抽象细节


    另一本书的解释是,查看第4.8节:

    我相信这是在试图生成一个可以通过标准C链接器链接的库时使用的

    将使用名称和类型对常规C符号名称进行编码,因此函数如下:

    #sample.h
    
    #ifndef SAMPLE_H
    #define SAMPLE_H
    
    //no header included or namespace declared here
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    //no header included or namespace declared too
    
    class Sample: public Parent
    {
    public:
        Sample();
        ~Sample();
    
        type0 fun(type1 val1, type2 val2);
        ...
    };
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif // SAMPLE_H
    
    int blah(double num);
    
    可能有一个类似“iblahd”的符号名 (或者类似的,我完全忘记了) 您可以看到,返回类型和参数类型在符号中

    extern C所做的一件事就是让它以常规的C方式查找符号,这只是“废话”

    我想,例如,这是用来创建一个有效的C++头,编译器尝试使用它,将与另一个C库中的符号产生链接。

    不使用Exc C,它将寻找一个具有C++名称的函数名/编码符号的共享库对象。 所以,更清楚地说,这是

    • 创建一个C++ API来封装C库。

      < LI>创建一个C++库,该库可以由C应用程序链接
    它还可能导致类结构的分配更像一个结构,而不能使用动态多态性,因此它的内存布局对于C来说可能是正确的 (不幸的是,时间太长了,我记不清了)

    即使出现了type0、type1和type2,它们自己的标题也不包括在这里,而是包含在cpp文件中(例如sample.h)。然而,当我调用类示例时,我必须包含这些标题(例如type0.h、type1.h、type2.h),这似乎很不方便

    您的意思是在调用
    func
    之前必须包含它们吗?如果是这样的话,它实际上是好的代码组织的主要部分。如果从不使用
    func
    ,则不需要包含这些类型的标题。只有涉及这些类型的函数调用才需要对类型进行完整定义,而不是函数声明

    标头不应包含超出使其自身包含编译的最小值的任何内容。只要有可能,其他事情应该只提前声明。标准库具有用于此目的的
    iosfwd
    头。因此,声明流运算符(
    )的类不需要拉取整个
    iostream

    调用站点,也恰好知道它要写入或读取的具体流,进行包含


    记住C++的设计理念:你不需要为你不需要的东西付费。

    同意;这是一个很差的头,对于一些理性的例子,头文件是一个足球蝙蝠-从我的经验,人们可以在数学或C++中好,但不是两者都:-)只有向前声明是必需的大多数“自包含”标题。由于fwd DECL缺失,且类型在单独的标题中明确引用。1。这个代码是纯C++(使用类),所以引用C视图没有意义。2.即使是C语言也需要向前声明用户定义的类型以使用指针。3.看起来不是这样的-
    type0
    type1
    type2
    看起来像非指针/非引用类型。我刚刚下载了提到的项目,示例代码并不存在。所以这是一个近似的问题。type0、type1等最有可能是指针类型。例如,项目中的blas.h文件对于C编译器来说是可以通过的。因为
    blas.h
    是纯C头文件,它不定义任何类,只定义自由函数。谢谢你的回答@马塔皮罗格鲁。由于我需要一些额外的功能,我尝试添加一些函数和派生。类型(例如,
    type0
    )可以是任何类型,而不仅仅是指针。您可以在BudgetedSVM/src/mm_algs中找到这样的标题。h@HansPassant那是