我遇到一个奇怪的问题,试图inline
我的“Person”类的访问器导致代码无法编译。
以下代码将成功编译并运行(使用Visual Studio 2012):
Person.h
#pragma once
#include <string>
using namespace std;
class Person
{
public:
Person(string name, int age = 0);
~Person(void);
// Accessors
string name(void) const;
int age (void) const;
private:
string m_name;
int m_age;
};
Person.cpp
#include "stdafx.h"
#include "Person.h"
Person::Person(string name, int age) :
m_name(name),
m_age (age )
{}
Person::~Person(void) {}
string Person::name(void) const
{
return m_name;
}
int Person::age(void) const
{
return m_age;
}
header_test.cpp
#include "stdafx.h"
#include <iostream>
#include "Person.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Person p("Joe");
cout << p.name() << endl;
return 0;
}
如果我将访问者更改为 inline
,则代码会中断。
在Person.h中内联访问者
// Accessors
inline string name(void) const;
inline int age (void) const;
在Person.cpp
中内联访问者inline string Person::name(void) const
{
return m_name;
}
inline int Person::age(void) const
{
return m_age;
}
执行此操作会产生以下错误:
1&gt; header_test.obj:错误LNK2019:未解析的外部符号“public:class std :: basic_string,class std :: allocator&gt; __thiscall Person :: name(void)const”(?name @ Person @@ QBE? AV?$ basic_string @ DU?$ char_traits @ D @ std @@ V?$ allocator @ D @ 2 @@ std @@ XZ)在函数_wmain中引用
1&gt;致命错误LNK1120:1个未解析的外部
上帝,错误信息是神秘的...感谢所有这些哦有用的信息Microsoft / Visual Studio!
我知道inline
关键字只是编译器的“提示”,可能在这里没有实际价值,但它仍然不应该破坏代码!
为什么会这样?
答案 0 :(得分:3)
我不是语言律师,所以我无法判断编译器的行为是否合法。然而,我可以解释正在发生的事情。
当您标记函数inline
时,您不暗示编译器可以内联此函数。由于超过10年,编译器不需要您的提示。他们知道什么时候内联。相反,你做了什么,你表明函数定义对于它所包含的每个翻译单元都是本地的。对于这个定义应该是可用的。
有效地说,name()
定义应该是每个.cpp
文件的本地定义,但是您并没有为每个.cpp
文件提供这个定义!我仍然认为编译器可以在此发出警告。
答案 1 :(得分:1)
如果要使用inline
关键字,则需要在标题中定义函数体。 inline
也不只是给编译器一个提示:它或多或少地关闭了&#34;一个定义&#34;规则*关于函数被定义一次且仅一次。
此外,如果在头文件中定义类成员函数,则ala
class Foo {
int bar() { return 5; }
};
他们得到了#34;内联&#34;默认情况下,没有理由输入关键字: - )
*技术上没有,但为了简单起见,您可以将其视为行为方式。请参阅SergeyA的以下评论。