C++ ⇒ VBA 書いて覚えるための初心者自己中記事

C++ ⇒ VBA 勉強の履歴を付けるというかノート代わりに使ってます

C++ using  書いて覚えるための初心者自己中記事

 

nenechi.hatenablog.com

 この記事で勉強したusing をもっと勉強するらしい。

 

まずこれを、

#include <iostream>
 
namespace Hoge {
	using namespace std;
}
 
int main() {
	Hoge::cout << "hello" << Hoge::endl;
 
	system("pause");
}

見たことない書き方。

新しい出会い。

#include <iostream>
 
namespace Hoge {
	using namespace std;
	void Hello() {
		cout << "hello" << endl;
	}
}
 
int main() {
	Hoge::Hello();
 
	system("pause");
}

 

 これも可能。

 

名前空間内でusing すると対象の名前空間はusing された場所の名前空間に取り込まれる。

取り込んで相手の能力を吸収。カービィかな?

using == カービィ

trueだな

で覚えよう。

 

いままでずっと使ってきたmain 関数の外、グローバル部分へのusingは

グローバルカービィにstd を吸わせていたのか。

グローバルカービィ 

 

別名 クローバル名前空間スコープ(グローバルスコープ)

 

Hoge内で using namespace std;  を書くと

coutは

std::cout であり、また

Hoge::cout  でもある。

なのでHoge名前空間内ではcout だけでOKとなる。

 

 名前空間スコープに限った話ではなくブロックスコープでも同じ。

 

 

次に

class Show {
public:
	static void Value(char ch) {//Show2 でオーバーロードライドされた
		cout << ch << endl;
	}
	static void Value(const char* str) {
		cout << str << endl;
	}
};
 
class Show2 :public Show{
public:
	static void Value(char ch) {//文字コードを出す仕様にした
		int n = static_cast<unsigned char>(ch);
		cout << n << endl;
	}
 
};
 
//静的メンバ関数はクラスのオブジェクトが無くても呼び出せる
 
int main() {
	Show2::Value('A');
	Show2::Value("Hoge");//使用できない。エラー
 
	system("pause");
}

 基底クラスでは引数が違う同名のメンバ関数があり

派生クラスではそのメンバ関数のうちの一つをオーバーロードライド。

 

この状態で派生クラスに対して2種類の引数のメンバ関数をそれぞれ呼び出す。

片方はShow2 でオーバーロードライドされたメンバ関数が呼び出された。

もう片方はオーバーロードライドされていないのでShowのメンバ関数が呼び出されると思いきやエラーになる。

 

 これは、そのまま

このような状態だと基底クラスのメンバ関数Show は全て使えなくなるらしい。

 

 

全て使えなくなるというと、俺は勘違いしてしまう。

Show2::Value('A');
Show::Value("Hoge");//直接指定すれば使える
//Show2::Value("Hoge");//使用できない。エラー

 直接呼び出せばもちろん使えるのだ。

 

・・・あれ?

オーバーロードとオーバーライドって違うか?

 ちょっと確認。

class Show {
public:
	static void Value(char ch) {//引数の違う同名関数 オーバーロード
		cout << ch << endl;
	}
	static void Value(const char* str) {//引数の違う同名関数 オーバーロード
		cout << str << endl;
	}
};
 
class Show2 :public Show{
public:
	static void Value(char ch) {//Showの同名メンバ関数を上書き オーバーライド
		int n = static_cast<unsigned char>(ch);
		cout << n << endl;
	}
};

 

引数の違う同名関数

-> オーバーロード

 

派生クラスで基底クラスのメンバ関数を処理を変更して上書き

-> オーバーライド

 

よし。

上の文章で間違ってたから直した。

 

つづき、

オーバーライドされていない基底クラスのShow関数まで使えなくなってしまうので困ってた。

これは基底クラスのすべてのオーバーロードされたShow関数を派生クラスでオーバーライドすれば一応解決する。

オーバーライドした関数内で基底クラスのShow関数を呼び出す。みたいな。

 

しかし、using を使えばもっとスマートに解決できるらしい。

(やっとusing来た)

class Show {
public:
	static void Value(char ch) {//引数の違う同名関数 オーバーロード
		cout << ch << endl;
	}
	static void Value(const char* str) {//引数の違う同名関数 オーバーロード
		cout << str << endl;
	}
};
 
class Show2 :public Show{
public:
	static void Value(char ch) {//Showの同名メンバ関数を上書き オーバーライド
		int n = static_cast<unsigned char>(ch);
		cout << n << endl;
	}
	using Show::Value; //ここでusing
};
 
//静的メンバ関数はクラスのオブジェクトが無くても呼び出せる
 
int main() {
	Show2::Value('A');
	Show::Value("Hoge");
	Show2::Value("Hoge");//使えるようになった
 
	system("pause");
}

 using Show::Value; //ここでusing

カービィがShowクラスのValueを取り込んだ

 

さらにこのusing はアクセス指定子に影響される。

class Show {
public:
	static void Value(char ch) {//引数の違う同名関数 オーバーロード
		cout << ch << endl;
	}
	static void Value(const char* str) {//引数の違う同名関数 オーバーロード
		cout << str << endl;
	}
};
 
class Show2 :public Show{
public:
	/*
	static void Value(char ch) {//Showの同名メンバ関数を上書き オーバーライド
		int n = static_cast<unsigned char>(ch);
		cout << n << endl;
	}
	*/
private:
	using Show::Value; //usingをprivate
};
 
//静的メンバ関数はクラスのオブジェクトが無くても呼び出せる
 
int main() {
	Show2::Value('A');//使えなくなった
	Show::Value("Hoge");
	Show2::Value("Hoge");//使えなくなった
 
	system("pause");
}

 

 今回は直接呼び出しているため、private になったVlaueが使えなくなった。

private なので内部からは使える。

Show :: Value の using が private

なのはわかる気がするけど、オーバーライドしたのもprivate 扱いになるのか。

 

usingここまで。