초보)c++ lnk2019,1120 오류입니다. 클래스 인라인 배우면서 빌드했는데 오류뜨네요 ㅠㅠ

플밍플밍의 이미지

class Fraction
{
private:
int m_nNumerator;
int m_nDenominator;

public:

inline void print() const;

void store(int nNumer, int nDenom)
{
m_nNumerator = nNumer;
m_nDenominator = nDenom;
}
};//Fraction.h
---------------------------------------------------------
#include "Fraction.h"
#include
using namespace std;

void Fraction::print() const
{
cout << m_nNumerator << " / " << m_nDenominator << endl;
}//Fraction.cpp
-------------------------------------------------------------
#include "Fraction.h"
#include
using namespace std;

int main()
{
Fraction fr1;
fr1.store(2, 3);
fr1.print();

return 0;
}
//소스.cpp

명시적,암묵적 인라인함수가 뭔지 배우면서 빌드한번해보려했는데 오류가뜨네요 ㅠㅠ
인터넷에서도 저오류는 원인이 여러가지라고해서 이것저것 해보는데도 해결이안되요
도와주세요~~

플밍플밍의 이미지

LNK2019 "public: void __thiscall Fraction::print(void)const " (?print@Fraction@@QBEXXZ) 외부 기호(참조 위치: _main 함수)에서 확인하지 못했습니다. lab5-1 c:\Users\Y\documents\visual studio 2015\Projects\lab5-1\lab5-1\소스.obj 1

LNK1120 1개의 확인할 수 없는 외부 참조입니다. lab5-1 c:\users\y\documents\visual studio 2015\Projects\lab5-1\Debug\lab5-1.exe 1

HDNua의 이미지

"c++ inline function separate file"로 구글에 검색해보면 이런 답변이 나옵니다.
http://stackoverflow.com/questions/3992980/c-inline-member-function-in-cpp-file

요약하면, 컴파일러는 inline 함수의 정의를 항상 알고 있어야 하기 때문에
inline 함수는 헤더/소스로 분리하여 정의할 수 없다는 것입니다.

원래는 표준 문서에서 이 내용을 찾아보려고 했는데, 내공 부족으로 도무지 찾을 수가 없더라구요.
이 부분은 다른 고수님께...

저는 이렇게 생각했습니다.

플밍플밍의 이미지

먼저 빠른 답변달아주신점 정말 감사합니다.
헤더파일에
void Fraction::print() const
{
cout << m_nNumerator << " / " << m_nDenominator << endl;
}
을 붙이니까 빌드가되네요
애초에 정의도 헤더파일에 해야됬던건가봐요

익명 사용자의 이미지

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

네. C++11 표준과 가장 가까운 드래프트인 n3337입니다. 뭐, 사실 이런 전통적인 문제에 있어서는 표준간 차이가 그닥 없어요.

7.1.2 Function specifiers

2 A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

3 A function defined within a class definition is an inline function. The inline specifier shall not appear on a block scope function declaration.90 If the inline specifier is used in a friend declaration, that declaration shall be a definition or the function shall have previously been declared inline.

4 An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [Note: A call to the inline function may be encountered before its definition appears in the translation unit. —end note]If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units. A static local variable in an extern inline function always refers to the same object. A string literal in the body of an extern inline function is the same object in different translation units. [Note: A string literal appearing in a default argument is not in the body of an inline function merely because the expression is used in a function call from that inline function. —end note] A type defined within the body of an extern inline function is the same type in every translation unit.

네. odr-used라는 낯선 개념을 끌어다 쓰는데다가 섹션 3.2를 링크하고 있죠. 사실 odr은 그 유명한 One definition rule을 가리키는 것이고, 섹션 3.2가 바로 그 규칙을 설명하는 부분입니다. 내용은 뭐 이렇죠.

3.2 One definition rule

1 No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

2 An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) is immediately applied. this is odr-used if it appears as a potentially-evaluated expression (including as the result of the implicit transformation in the body of a non-static member function (9.3.1)). A virtual member function is odr-used if it is not pure. A non-overloaded function whose name appears as a potentially-evaluated expression or a member of a set of candidate functions, if selected by overload resolution when referred to from a potentially-evaluated expression, is odr-used, unless it is a pure virtual function and its name is not explicitly qualified. [Note: This covers calls to named functions(5.2.2),operator overloading (Clause 13), user-defined conversions (12.3.2), allocation function for placement new (5.3.4), as well as non-default initialization (8.5). A copy constructor or move constructor is odr-used even if the call is actually elided by the implementation. —end note] An allocation or deallocation function for a class is odr-used by a new expression appearing in a potentially-evaluated expression as specified in 5.3.4 and 12.5. A deallocation function for a class is odr-used by a delete expression appearing in a potentially-evaluated expression as specified in 5.3.5 and 12.5. A non-placement allocation or deallocation function for a class is odr-used by the definition of a constructor of that class. A non-placement deallocation function for a class is odr-used by the definition of the destructor of that class, or by being selected by the lookup at the point of definition of a virtual destructor(12.4).26 A copy-assignment function for a class is odr-used by an implicitly defined copy-assignment function for another class as specified in 12.8. A move-assignment function for a class is odr-used by an implicitly-defined move-assignment function for another class as specified in 12.8. A default constructor for a class is odr-used by default initialization or value initialization as specified in 8.5. A constructor for a class is odr-used as specified in 8.5. A destructor for a class is odr-used as specified in 12.4.

3 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.

네. unevaluated operand 같은 새 개념을 Clause 5에서 또 인용해서 쓰고 있는데, 더 이상은 본문 안 옮겨올테니 관심있으시면 가서 보고 오세요. ~_~

교훈:
1. 인라인 함수는 그것이 사용되는 모든 해석 단위에서 정의되어야 하며 그 모든 정의가 일치해야 합니다. ("사용되는"과 "odr-used" 사이의 미묘한 차이에 대해서는 뭐 크게 신경쓰지 말도록 하죠.)

2. 뭐 꼭 헤더 파일에다가 정의해 놓을 필요는 없습니다. 표준이 그렇게 요구하진 않는단 얘기죠. 하지만 그게 제일 쉽고 보편적인 방법이기는 해요.

3. 컴파일러는 인라인 함수를 반드시 인라인 호출하지 않아도 되는데, 그 경우에도 프로그래머는 상기한 인라인 함수에 요구되는 조건들을 만족시켜줘야 됩니다.

4. C++ 표준을 뒤적거리는 건 그 권위에 의존해야 하는 경우에만 의미가 있을 뿐 그다지 교육적 의미는 없으며, 특히 전문을 다 읽지 않고 필요한 부분만 읽어 이해하려는 시도는 짜증나리만치 어렵습니다. 아오.

HDNua의 이미지

답변 달아주셔서 감사합니다.

저는 이렇게 생각했습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.