developer tip

.cpp 파일의 C ++ 인라인 멤버 함수

copycodes 2020. 11. 5. 08:12
반응형

.cpp 파일의 C ++ 인라인 멤버 함수


인라인 멤버 함수는 정의에 따라 헤더에 들어가야한다는 것을 알고 있습니다. 그러나 함수 구현을 헤더에 넣을 수 없다면 어떻게 될까요? 이 상황을 보자 :

파일 Ah

#pragma once
#include "B.h"

class A{
    B b;
};

파일 Bh

#pragma once

class A; //forward declaration

class B{
    inline A getA();
};

순환 포함으로 인해 구현 getA

B.cpp

#include "B.h"
#include "A.h"

inline A B::getA(){
    return A();
}

컴파일러가 인라인 getA됩니까? 그렇다면 어떤 인라인 키워드가 중요한 키워드입니까 (헤더에있는 키워드 또는 .cpp 파일에있는 키워드)? 인라인 멤버 함수의 정의를 .cpp 파일에 넣는 다른 방법이 있습니까?


C ++ FAQ 에서 인용 :

참고 : 함수가 단일 .cpp 파일에서만 사용되지 않는 한, 함수 정의 ({...} 사이의 부분)는 헤더 파일에 배치해야합니다. 특히 인라인 함수의 정의를 .cpp 파일에 넣고 다른 .cpp 파일에서 호출하면 링커에서 "해결되지 않은 외부"오류가 발생합니다.

컴파일러 는 해당 인라인 함수의 사용을 발견 할 때마다 인라인 함수 정의 를 확인해야 합니다. 일반적으로 인라인 함수가 헤더 파일에있는 경우 가능합니다.

컴파일러가 getA를 인라인합니까?

아니요, 사용이 getA()B.cpp 자체에 있는 경우를 제외하고 는.

그렇다면 어떤 인라인 키워드가 중요한 키워드입니까 (헤더에있는 키워드 또는 cpp에있는 키워드)?

모범 사례 : 클래스 본문 외부의 정의에서만.

인라인 멤버 함수의 정의를 cpp 파일에 넣는 또 다른 방법이 있습니까?

아니, 적어도 모르겠다.


B.cpp의 범위를 벗어나는 것은 불가능합니다. 컴파일러는 컴파일 단위별로 작동합니다. 즉, 각 .cpp 파일을 개별적으로 컴파일하므로 C.cpp를 컴파일하면 getA ()에 대한 코드를 사용할 수 없으며 함수 호출을 수행해야합니다. 링커가 문제를 해결하도록합니다 (또는 실제로 단어를 사용하여 인라인하려고하면 링커 오류가 발생합니다. inline와 비슷한 특성이 있음 static).

유일한 예외는 LTCG, 즉 최신 컴파일러에서 사용할 수있는 링크 타임 코드 생성입니다.

이 경우 한 가지 방법은 인라인 코드를 포함하는 다른 헤더 파일 (때때로 * .inl 파일로 명명 됨)을 갖는 것입니다.

편집 : 어떤 인라인이 관련되어 있는지-클래스 정의, 즉 헤더 파일에있는 것입니다. 많은 컴파일러는 인라인 될 수있는 것과 인라인되어야하는 것에 대해 자신의 생각을 가지고 있음을 명심하십시오. 예를 들어 gcc는 인라인을 완전히 비활성화 (-O0)하거나 인라인 할 가치가 있다고 판단되는 모든 것을 인라인 할 수 있습니다 (예 : -O3).


나는 반대 방향에서 이것을 할 것입니다.

함수에 인라인 선언을 추가하지 마십시오 (필요하지 않은 경우).

함수 / 메소드에 인라인 선언을 추가해야하는 유일한 경우는 헤더 파일에 함수를 정의하지만 클래스 선언 외부에있는 경우입니다.

Xh

class X
{
    public:
        int getX()   { return 4;} // No inline because it is part of the class.
                                  // The compiler knows that needs an inline tag
        int getY();
        int getZ();
};

inline
int X::getY()  { return 5;}       // This needs to be explicitly declared inline.
                                  // Otherwise the linker will complain about
                                  // multiple definitions in compilation units.

X.cpp

 // Never declare anything inline in the cpp file.

 int X::getZ() { return 6; }

당신에게 더 구체적인 경우.
모든 인라인 사양을 제거합니다. 그들은 당신이 생각하는 것을하고 있지 않습니다.


These days, most compilers can perform inlining at link time, as well as compile time. If your function is likely to benefit from inlining, then the Link Time optimizer is likely to do just that.

By the time the linker gets to it, not much about the inline status of compiler output is available, except that the compiler will flag certain objects as being collectible, for instance because an inline function or class template instance appears in multiple compilation units, or it should raise an error when multiple symbols share a name, such as the main function being defined twice. None of this has influence on the actual code it will generate.


Here is the way I did it.

File A.h

#pragma once
#include "B.h"

class A {
    B b;
};

File B.h

#pragma once

class B {
public:
    template<class T> inline T getA() {
        assert(NULL); // Use 'getA<A>()' template specialization only!
        return NULL;
    }
};

class A; // Forward declaration
template<> inline A B::getA<A>();

File C.h

#pragma once
#include "A.h"
#include "B.h"

// Implement template specialization here!
template<> inline A B::getA<A>() { return A(); }

Just include the "C.h" file to be able to use getA() method. The only change with the original code is that the getA() method must be defined as public instead of private.

However, as many of you explained it, this is not really useful.


ISO/IEC 14882:2014

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

참고URL : https://stackoverflow.com/questions/3992980/c-inline-member-function-in-cpp-file

반응형