2017年10月29日
《その98》 ヘッダ内の非メンバ関数(p.439演習12-2)
ヘッダ内で定義する非メンバ関数
ヘッダ Abc.h と、二つのソースファイル source1.cpp, source2.cpp とで構成されるプログラムがあるとします。
また、関数 func1 は、ヘッダ Abc.h の中で定義されるクラス Clss のメンバ関数であり、
関数 func2 は、ヘッダ Abc.h 内で定義されているがクラスの非メンバ関数であるものとします。
クラスの中で定義されたメンバ関数はインライン関数になります。
インライン関数は内部結合を持つので、source1.cpp と source2.cpp の二つのソースファイルが同じヘッダ Abc.h をインクルードしたとしても、
Abc.h 内で定義されているクラス Clss のメンバ関数 func1 の二重定義エラーは発生しません。
一方、クラスの非メンバ関数は外部結合を持つので、source1.cpp と source2.cpp の二つのソースファイルは、それぞれ単体では問題なくヘッダ Abc.h をインクルードできるものの、リンク時に非メンバ関数 func2 の二重定義エラーが発生してしまいます。
したがって、クラスの非メンバ関数をヘッダ内で定義する場合には、関数に inline あるいは static を付けて内部結合を持たせる必要があります。
新版明解C++入門編 p.439 演習12-2
下記のクラス Boolean に対して、v が False であれば bool型の true を、
True であれば bool型の false を返却する演算子関数 ! を追加せよ。
------------------------------------------
// Boolean.h------------------------------------------
#ifndef ___Class_Boolean
#define ___Class_Boolean
#include
class Boolean {
public:
enum boolean { False, True };
private:
boolean v;
public:
Boolean() : v(False) { }
Boolean(int val) : v(val == 0 ? False : True) { }
operator int() const { return v; }
operator const char*() const { return v == False ? "False" : "True"; }
};
inline std::ostream& operator<<(std::ostream& s, Boolean& x) {
return s << static_cast(x);
}
#endif
以下が、演算子関数 ! を追加したヘッダとそれを利用するプログラムです。
// Boolean.h
#ifndef ___Class_Boolean
#define ___Class_Boolean
#include <iostream>
class Boolean {
public:
enum boolean { False, True };
private:
boolean v;
public:
Boolean() : v(False) { }
Boolean(int val) : v(val == 0 ? False : True) { }
operator int() const { return v; }
operator const char*() const { return v == False ? "False" : "True"; }
bool operator!() const { return v == False; }
};
inline std::ostream& operator<<(std::ostream& s, Boolean& x) {
return s << static_cast<const char*>(x);
}
#endif
// BooleanTest.cpp
#include <iostream>
#include "Boolean.h"
using namespace std;
int main() {
int n;
Boolean a ; cout << a << '\n';
Boolean b = 0; cout << b << '\n';
Boolean c(1) ; cout << c << '\n';
Boolean d(2) ; cout << d << '\n';
cout << '\n';
cout << boolalpha << !a << '\n';
cout << !c << '\n';
}
--
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/6911865
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック