アフィリエイト広告を利用しています

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

2017年12月15日

《その179》 using宣言によるアクセス権の調整 & p.174演習4-3


 using宣言によるアクセス権の調整

 次のプログラムで、基底クラス Base は、
private:
  int型の a
public:
  コンストラクタ Base
  関数 func1

で構成されています。

 また、基底クラス Base から private派生によって作られる派生クラス Derived は、実装された基底クラスのメンバに加えて、
private:
  int型の b
public:
  コンストラクタ Derived
  関数 func2

で構成されています。

 private派生であるため、基底クラス Base では公開メンバであった 関数 func1 は、派生クラス Derived においては、基本的には外部から呼び出すことができません。
 この func1 のアクセス権を using宣言により調整することができます。アクセス権を調整することによって、派生クラス Derived の外部から、関数 func1 を呼び出せるようにできるのです。

 下の ★1. の箇所が using宣言です。★2. の箇所で、アクセス権を調整して使えるようになった func1 を利用しています。

// ------------------------------------
#include <iostream>
class Base {
int a;
public:
Base(int aa) : a(aa) { }
void func1() const {
std::cout << "a = " << a << '\n';
}
};

class Derived : private Base {
int b;
public:
Derived(int aa, int bb) : Base(aa), b(bb) { }
void func2() const {
std::cout << "b = " << b << '\n';
}
using Base::func1; // ★1.
};

int main()
{
Derived drvd(11, 22);
drvd.func1(); // ★2.
drvd.func2();
}
// ------------------------------------

f04_0009.png


新版明解C++中級編 p.174 演習4-3
 次のクラス Base型と Derived型に対して、アップキャストとダウンキャストを試みるプログラムを作成せよ。

// ------------------------------------
class Base {
int a;
int b;

public:
Base(int aa, int bb) : a(aa), b(bb) { }

void func() const {
std::cout << "a = " << a << '\n';
std::cout << "b = " << b << '\n';
}
};

class Derived : public Base {
int x;

public:
Derived(int aa, int bb, int xx) : Base(aa, bb), x(xx) { }

void method() const {
func();
std::cout << "x = " << x << '\n';
}
};
// ------------------------------------

◆以下が解答のプログラムです。

// p174_演習4-3
#include <iostream>

class Base {
int a;
int b;

public:
Base(int aa, int bb) : a(aa), b(bb) { }

void func() const {
std::cout << "a = " << a << '\n';
std::cout << "b = " << b << '\n';
}
};

class Derived : public Base {
int x;

public:
Derived(int aa, int bb, int xx) : Base(aa, bb), x(xx) { }

void method() const {
func();
std::cout << "x = " << x << '\n';
}
};

int main()
{
Base base(10, 20);
Derived drvd(11, 22, 33);

// ◆ ------------------▽
Base* ptr_b1 = &base;

ptr_b1->func(); // a = 10
// b = 20
// ptr_b1->method(); /* エラー */
// ---------------------△

// ◆ アップキャスト----▽
Base* ptr_b2 = &drvd;

ptr_b2->func(); // a = 11
// b = 22
// ptr_b2->method(); /* エラー */
// ---------------------△

// ◆ ダウンキャスト----▽
// Derived* ptr_d1 = &base; /* エラー */
// ---------------------△

// ◆ ------------------▽

Derived* ptr_d2 = &drvd;

ptr_d2->func(); // a = 11
// b = 22
ptr_d2->method(); // a = 11
// b = 22
// x = 33
}
// ---------------------△


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





《その178》 クラスのメンバーへのアクセス


 クラスのメンバーが、例えば、次の a, b, c である場合、

private:
int a;
protected:
int b;
public:
int c;

a には、定義されたクラスの メンバー関数,フレンド関数からアクセスできます。
b には、定義されたクラスやその派生クラスの メンバー関数,フレンド関数からアクセスできます。
c には、どこからでもアクセスできます。

 さらに、このクラスからの private派生,protected派生,public派生 による派生クラスの場合には、a, b, c へのアクセス可否がどのようになるのか、一応、確認してみました。


// ------------------------------------
using namespace std;

/* 基底クラス(親クラス) */
class Class00 {
private:
int a;
protected:
int b;
public:
int c;
Class00() : a(10), b(20), c(30) { }
void get_a() { cout << a << '\n'; }
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
};

// ------------------

/* private派生(子クラス) */
class Class11 : private Class00 {
public:
// void get_a() { cout << a << '\n'; } // エラー
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
};

/* private派生(孫クラス) */
class Class12 : private Class11 {
public:
// void get_a() { cout << a << '\n'; } // エラー
// void get_b() { cout << b << '\n'; } // エラー
// void get_c() { cout << c << '\n'; } // エラー
};

// ------------------

/* protected派生(子クラス) */
class Class21 : protected Class00 {
public:
// void get_a() { cout << a << '\n'; } // エラー
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
};

/* protected派生(孫クラス) */
class Class22 : protected Class21 {
public:
// void get_a() { cout << a << '\n'; } // エラー
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
};

// ------------------

/* public派生(子クラス) */

class Class31 : public Class00 {
public:
// void get_a() { cout << a << '\n'; } // エラー
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
// ゲッタ get_a(), get_b(), get_c()は public の
// ままで継承されているので記述不要。

};

/* public派生(孫クラス) */
class Class32 : public Class31 {
public:
// void get_a() { cout << a << '\n'; } // エラー
void get_b() { cout << b << '\n'; }
void get_c() { cout << c << '\n'; }
// ゲッタ get_a(), get_b(), get_c()は public の
// ままで継承されているので記述不要。

};

int main() {
Class00 c00;
// cout << c00.a << '\n'; // エラー
// cout << c00.b << '\n'; // エラー
cout << c00.c << '\n'; // 30

Class11 c11;
// cout << c11.a << '\n'; // エラー
// cout << c11.b << '\n'; // エラー
// cout << c11.c << '\n'; // エラー

Class21 c21;
// cout << c21.a << '\n'; // エラー
// cout << c21.b << '\n'; // エラー
// cout << c21.c << '\n'; // エラー

Class31 c31;
// cout << c31.a << '\n'; // エラー
// cout << c31.b << '\n'; // エラー
cout << c31.c << '\n'; // 30

Class12 c12;
Class22 c22;
Class32 c32;

c00.get_a(); // 10
c00.get_b(); // 20
c00.get_c(); // 30

c11.get_b(); // 20
c11.get_c(); // 30

c21.get_b(); // 20
c21.get_c(); // 30

c22.get_b(); // 20
c22.get_c(); // 30

c31.get_b(); // 20
c31.get_c(); // 30

c32.get_b(); // 20
c32.get_c(); // 30
}


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)






 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2017年12月 >>
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。