C++中的inline函数的实现部分应该放在哪里呢?
C++中的inline函数的实现部分到底该放在哪里呢?
C++中的类中inline函数的实现部分究竟放在哪里? 下面是两位专家的说法:
下面引自林锐博士的《高质量C++编程》P67
定义在类声明之中的成员函数将自动地成为内联函数,例如
class A
{
public:
void Foo(int x,int y);{ } // 自动地成为内联函数
}
将成员函数的定义体放在类声明之中虽然能带来书写上的方便,但不是一种良好的编程风格,上例应该改成:
// 头文件:
class A
{
public:
void Foo(int x, int y);
}
// 定义头文件
inline void A::Foo(int x, int y)
{
}
C++的发明者Bjarne Stroustrup博士在他所著的书《C++语言的设计和演化》中则是这样论述这个问题(见《C++语言的设计和演化》P12):
在带类的C中只有成员函数能做成在线(注:也就是设计为inline函数)的,而要求函数成为在线只有一种方式,那就是把它的放进类的声明之中。例如:
class stack
{
/* … /*
char pop()
{
If(top<=min) error(“stack underflow”);
return *--top;
}
};
事实上,那时也看到这会使类的声明显得比较杂乱。另一方面,这看起来也是个好东西,因为它不鼓励在线函数的过度使用。关键字inline和允许在线成员函数的功能都是后来由C++提供的。例如,在C++中可以写下面这样的代码:
class stack
{
/* … /*
char pop();
};
Inline char stack:: pop()
{
If(top<=min) error(“stack underflow”);
return *--top;
}
照两位专家的说法,inline函数的实现代码似乎既可以放在.h文件,也可以放在.cpp文件。实际上是不是这样呢?我使用VC6.0做了一个测试程序(Win32控制台程序):
程序运行环境:英文版Win Xp sp2
程序编译环境:VC++ 6.0
首先我把inline函数的实现代码可以放在.h文件
测试程序如下:
// MyString.h
#ifndef MY_STRING_H
#define MY_STRING_H
#include <string.h>
class CMyString
{
private:
char *pszData;
public:
CMyString();
CMyString(char *psz);
int GetLength()
{
return strlen(pszData);
}
~CMyString();
};
#endif
#endif
// MyString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
CMyString::CMyString()
{
pszData = new char[20];
}
CMyString::CMyString(char *psz)
{
pszData = new char[20];
strcpy(pszData,psz);
}
CMyString::~CMyString()
{
delete []pszData;
pszData = NULL;
}
// TestString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
int main(int argc, char* argv[])
{
CMyString str("Hello World!");
int strlen = str.GetLength();
cout<<strlen<<endl;
return 0;
}
程序编译运行成功。
现在我把inline函数的实现代码可以放在.cpp文件(主要修改了MyString.h和MyString.cpp)
// MyString.h
#ifndef MY_STRING_H
#define MY_STRING_H
#include <string.h>
class CMyString
{
private:
char *pszData;
public:
CMyString();
CMyString(char *psz);
int GetLength();
~CMyString();
};
#endif
// MyString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
CMyString::CMyString()
{
pszData = new char[20];
}
CMyString::CMyString(char *psz)
{
pszData = new char[20];
strcpy(pszData,psz);
}
inline int CMyString::GetLength()
{
return strlen(pszData);
}
CMyString::~CMyString()
{
delete []pszData;
pszData = NULL;
}
// TestString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
int main(int argc, char* argv[])
{
CMyString str("Hello World!");
int strlen = str.GetLength();
cout<<strlen<<endl;
return 0;
}
程序编译不出错,但是运行出错,错误信息如下:
TestString.cpp
Generating Code...
Linking...
TestString.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMyString::GetLength(void)" (?GetLength@CMyString@@QAEHXZ)
Debug/TestString.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
TestString.exe - 2 error(s), 0 warning(s)
值得注意的是假如我在类CMyString添加一个成员函数GetInfo()。将程序改为
// MyString.h
#ifndef MY_STRING_H
#define MY_STRING_H
#include <string.h>
class CMyString
{
private:
char *pszData;
public:
CMyString();
CMyString(char *psz);
int GetLength();
void GetInfo();
~CMyString();
};
#endif
// MyString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
CMyString::CMyString()
{
pszData = new char[20];
}
CMyString::CMyString(char *psz)
{
pszData = new char[20];
strcpy(pszData,psz);
}
inline int CMyString::GetLength()
{
return strlen(pszData);
}
void CMyString::GetInfo()
{
int strlen = GetLength();
cout<<strlen<<endl;
}
CMyString::~CMyString()
{
delete []pszData;
pszData = NULL;
}
// TestString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <iostream.h>
int main(int argc, char* argv[])
{
CMyString str("Hello World!");
int strlen = str.GetLength();
cout<<strlen<<endl;
return 0;
}
在这种情况下即使把inline函数的实现代码可以放在.cpp文件,程序依然能运行成功。这个我实在搞不懂了。我想这是不是VC6.0对C++标准的一个不兼容的地方呢?