ページへ戻る
印刷
技術系備忘録/C++/最適化小手先テクニック/空関数の実体はヘッダに書くべし
をテンプレートにして作成 ::
シンクリッジ
xpwiki
:技術系備忘録/C++/最適化小手先テクニック/空関数の実体はヘッダに書くべし をテンプレートにして作成
開始行:
何もしない関数というのは、たまに登場してしまうと思います。
定義はあるけど、実体(.cpp)を見ると、中身がカラというケー...
クラスのコンストラクタやデストラクタに多い気がしますので...
-List1
--test.h
#prettify{{
class CTest
{
public:
CTest();
virtual ~CTest();
void func();
};
}}
--test.cpp
#prettify{{
CTest::CTest()
{}
CTest::~CTest()
{}
void CTest::func()
{
::AfxMessageBox( _T("func") );
}
}}
--main.cpp
#prettify{{
#include "test.h"
main()
{
CTest test;
test.func();
}
}}
リスト1の CTest のコンストラクタとデストラクタは何もして...
普通に VisualStudio のクラスウィザードでクラスを作ると勝...
コンパイラの最適化処理で、main() では、CTest::Func だけコ...
main() での処理は、
・CTest のコンストラクタをコール。
・CTest::func をコール。
・CTest のデストラクタをコール。
となり、実質不要なコンストラクタとデストラクタの関数をコ...
コンパイラは、関数をまたぐ最適化はしてくれないと思ってい...
コンパイラは、main.cppをコンパイルしている時に、CTestのコ...
こういう場合、クラス定義(ヘッダ)の中に、関数の実体を記...
-List2
--test.h
#prettify{{
class CTest
{
public:
CTest(){} // 空関数の実体も記述
virtual ~CTest(){} // 空関数の実体も記述
void func();
};
}}
--test.cpp
#prettify{{
/* .cpp には実体を書かない。
CTest::CTest()
{}
CTest::~CTest()
{}
*/
void CTest::func()
{
::AfxMessageBox( _T("func") );
}
}}
--main.cpp
#prettify{{
#include "test.h"
main()
{
CTest test;
test.func();
}
}}
リスト2のようにすることで、main() での処理は、
・CTest::func をコール。
だけになります。
しかし、最適化されないような例をあげます。
例えば、CTestのメンバ変数にクラスが含まれているような場合...
-List3
--test.h
#prettify{{
class CTest
{
public:
std::string m_str;
public:
CTest(){} // 空関数の実体も記述
virtual ~CTest(){} // 空関数の実体も記述
void func();
};
}}
こういう場合は、m_str を初期化する必要があるので、コンパ...
/*
ちなみに、上記例程度のメンバ変数ならばインライン処理して...
*/
もう一つ最適化されないケース。
virtual 関数の場合、派生先関数がコールされる場合があるの...
-List4
--test.h
#prettify{{
class CTest
{
public:
virtual void func(){} // 空関数の実体が記述されていても
};
}}
--main.cpp
#prettify{{
void function(CTest *p)
{
p->func(); // ここではちゃんとコールする
}
}}
まとめ。
関数をヘッダに実装をすれば、コンパイラが勝手にインライン...
例えば、全ての関数のヘッダに実装するのは、コード最適化の...
どの程度までの関数をヘッダに実装するかの判断は、ケースバ...
物によっては、まったく意味が無いケースもありますが、最適...
終了行:
何もしない関数というのは、たまに登場してしまうと思います。
定義はあるけど、実体(.cpp)を見ると、中身がカラというケー...
クラスのコンストラクタやデストラクタに多い気がしますので...
-List1
--test.h
#prettify{{
class CTest
{
public:
CTest();
virtual ~CTest();
void func();
};
}}
--test.cpp
#prettify{{
CTest::CTest()
{}
CTest::~CTest()
{}
void CTest::func()
{
::AfxMessageBox( _T("func") );
}
}}
--main.cpp
#prettify{{
#include "test.h"
main()
{
CTest test;
test.func();
}
}}
リスト1の CTest のコンストラクタとデストラクタは何もして...
普通に VisualStudio のクラスウィザードでクラスを作ると勝...
コンパイラの最適化処理で、main() では、CTest::Func だけコ...
main() での処理は、
・CTest のコンストラクタをコール。
・CTest::func をコール。
・CTest のデストラクタをコール。
となり、実質不要なコンストラクタとデストラクタの関数をコ...
コンパイラは、関数をまたぐ最適化はしてくれないと思ってい...
コンパイラは、main.cppをコンパイルしている時に、CTestのコ...
こういう場合、クラス定義(ヘッダ)の中に、関数の実体を記...
-List2
--test.h
#prettify{{
class CTest
{
public:
CTest(){} // 空関数の実体も記述
virtual ~CTest(){} // 空関数の実体も記述
void func();
};
}}
--test.cpp
#prettify{{
/* .cpp には実体を書かない。
CTest::CTest()
{}
CTest::~CTest()
{}
*/
void CTest::func()
{
::AfxMessageBox( _T("func") );
}
}}
--main.cpp
#prettify{{
#include "test.h"
main()
{
CTest test;
test.func();
}
}}
リスト2のようにすることで、main() での処理は、
・CTest::func をコール。
だけになります。
しかし、最適化されないような例をあげます。
例えば、CTestのメンバ変数にクラスが含まれているような場合...
-List3
--test.h
#prettify{{
class CTest
{
public:
std::string m_str;
public:
CTest(){} // 空関数の実体も記述
virtual ~CTest(){} // 空関数の実体も記述
void func();
};
}}
こういう場合は、m_str を初期化する必要があるので、コンパ...
/*
ちなみに、上記例程度のメンバ変数ならばインライン処理して...
*/
もう一つ最適化されないケース。
virtual 関数の場合、派生先関数がコールされる場合があるの...
-List4
--test.h
#prettify{{
class CTest
{
public:
virtual void func(){} // 空関数の実体が記述されていても
};
}}
--main.cpp
#prettify{{
void function(CTest *p)
{
p->func(); // ここではちゃんとコールする
}
}}
まとめ。
関数をヘッダに実装をすれば、コンパイラが勝手にインライン...
例えば、全ての関数のヘッダに実装するのは、コード最適化の...
どの程度までの関数をヘッダに実装するかの判断は、ケースバ...
物によっては、まったく意味が無いケースもありますが、最適...
ページ名: