底辺大学の院生がプログラミングや機械学習を勉強するブログ

勉強していることを雑にまとめるブログ。当然、正しさの保証は一切しない。

コンストラクタ初期化子を使う

多分知ってる人からしたら今更な内容。



今までコンストラクタでメンバ変数を初期化する際はこんなコードを書いてた。

MyClass(const int value) { value_ = value; }

これと同じことが下のコードでもできる。

MyClass(const int value) : value_(value) {}

何が違うの?という感じだし読みにくいから前者で書いてたけど、調べたら微妙に違うらしい。
どうやら、前者が宣言してから代入しているのに対して、後者は宣言と同時に初期化をしているようだ。

つまり、

int value_;
value_ = 1;

と、

int value_ = 1;

の違い。全く知らんかった……。
見ての通りでわかるけど処理時間は下のように書いた方が若干早いらしい。


もちろんメンバ変数がポインタでも初期化できる。

MyClass(const int value) : value_(new int(value)) {}

うん、最初可読性云々書いたけどこっちのほうが格好いい気がしてきた。


おまけ

一様分布に従う乱数を作る関数オブジェクトを書き換える。

#include <iostream>
#include <random>
#include <ctime>
#include <limits>

template<class Ty_ = int>
class UniformRand
{
private:
	std::mt19937* mt_;
	std::uniform_int_distribution<Ty_>* ud_;
public:
	explicit UniformRand(const Ty_ min = 0, const Ty_ max = std::numeric_limits<Ty_>::max(), const long seed = static_cast<long>(time(0))) :
		ud_(new std::uniform_int_distribution<Ty_>(min, max)),
		mt_(new std::mt19937(seed)) {}
	~UniformRand(void) { delete mt_; delete ud_; }
	Ty_ operator()(void) const { return ud_->operator()(*mt_); }
};

int main()
{
	UniformRand<> uRand(0, 10);
	for (int i = 0; i < 10; i++)
	{
		std::cout << uRand() << std::endl;
	}
	return EXIT_SUCCESS;
}