2011年10月28日金曜日

オーバーライド時のアクセス修飾子変更 C++ 編

PHP 編Java 編C# 編に続き、 C++ でも検証。C++ は好きだがこれも慣れていないため、怪しいかも・・・

まず、親クラス。
class ParentClass
{
private:
  virtual void func1() { std::cout << "Parent private func1" << std::endl; }
protected:
  virtual void func2() { std::cout << "Parent protected func2" << std::endl; }
public:
  virtual void func3() { std::cout << "Parent public func3" << std::endl; }
 
public:
  virtual ~ParentClass() {}
  virtual void call()
  {
    func1();
    func2();
    func3();
  }
};
private, protected, public の 3 種類のメソッドと、それらを呼び出すメソッドを作成。

子クラス1 は public に変更。
class Child1Class : public ParentClass
{
public:
  virtual void func1() { std::cout << "Child1 private -> public func1" << std::endl; }
  virtual void func2() { std::cout << "Child1 protected -> public func2" << std::endl; }
  virtual void func3() { std::cout << "Child1 public func3" << std::endl; }
  virtual ~Child1Class() {}
};
シンタックスエラーは起きない。

子クラス2 は protected に変更。
class Child2Class : public ParentClass
{
protected:
  virtual void func1() { std::cout << "Child2 private -> protected func1" << std::endl; }
  virtual void func2() { std::cout << "Child2 protected func2" << std::endl; }
  virtual void func3() { std::cout << "Child2 protected -> protected func3" << std::endl; }
public:
  virtual ~Child2Class() {}
};
これもシンタックスエラーは起きない。

子クラス3 は private に変更。
class Child3Class : public ParentClass
{
private:
  virtual void func1() { std::cout << "Child3 private func1" << std::endl; }
  virtual void func2() { std::cout << "Child3 protected -> private func2" << std::endl; }
  virtual void func3() { std::cout << "Child3 public -> private func3" << std::endl; }
public:
  virtual ~Child3Class() {}
};
これもシンタックスエラーは起きない。

実行してみると、
ParentClass* p = new ParentClass();
p->call();
std::cout << "----------" << std::endl;
delete p;

Child1Class* c1 = new Child1Class();
c1->call();
std::cout << "----------" << std::endl;
delete c1;

Child2Class* c2 = new Child2Class();
c2->call();
std::cout << "----------" << std::endl;
delete c2;

Child3Class* c3 = new Child3Class();
c3->call();
delete c3;
結果は、
Parent private func1
Parent protected func2
Parent public func3
----------
Child1 private -> public func1
Child1 protected -> public func2
Child1 public func3
----------
Child2 private -> protected func1
Child2 protected func2
Child2 protected -> protected func3
----------
Child3 private func1
Child3 protected -> private func2
Child3 public -> private func3

全てのパターンで特に制限なく変更出来ている。
Java とかと逆の制限があったような気がするが、気のせいだったか。

何か間違っている可能性も・・・

Cygwin g++ (GCC) 4.5.3
Visual C++ 2010
でコンパイル。 いくつかの言語で試してみたものの、結果まぁ言語仕様書を読めよということで。

0 件のコメント:

コメントを投稿