Top/article/Inheritance-of-virtual-methods-and-default-parameters
English | Japanese
English | Japanese

Menu

  • Top
  • Akihiko Yamaguchi 山口 明彦
  • Project プロジェクト
  • Text テキスト
  • Recent articles 最近の記事
  • Articles 記事一覧 (a to z)
  • Search 検索

Tags タグ †

  • [c++][bash][python][latex][php]
  • [linux][windows][mac][android]
  • [math][algorithm][idea][trick]
  • [liboctave][opencv][git][ros]
  • [setting][bug][general]
↑

Recent articles 最近の記事 †

2019-07-02
  • article/Display-Unix-Time
  • article/Synchronize-Linux-Time-to-Remote
2018-09-27
  • article/python-multimode-singleton
2018-09-02
  • article/rosinstall-git-default-remote
2017-07-28
  • article/SubMenu
2017-03-05
  • article/Import-a-different-version-of-OpenCV-in-Python
2015-08-17
  • article/DRC-finals-2015
2015-01-05
  • article/Upgrade-Android-to-Lollipop
2015-01-01
  • article/Kernel-panic-of-Linux-when-using-Xtion
  • article/Do-not-skip-freeing-data-when-using-tri-mesh-in-ODE
Access: 1/1639 - Admin
These search terms have been highlighted:[c++]

Inheritance of virtual methods and default parameters

仮想関数の継承とデフォルトパラメータの関係

[c++]
2008-10-28

デフォルトパラメータを持つ仮想関数を継承する場合の振る舞いを調べてみた.仮想関数は「動的に結合」される一方,デフォルトパラメータは「静的に結合」される. 例えば,以下の簡単なクラスを考えよう:

class TBase
{
protected:
  int x;
public:
  TBase (void) : x(0) {};
  ~TBase (void) {};
  int getX(void) const {return x;};
  virtual void increment (int add=1) = 0;
};

class TTest : public TBase
{
public:
  TTest (void) {};
  ~TTest (void) {};
  /*override*/void increment (int add=-1)
    {x+= add;};
};

このとき,

  TTest t;
  TBase &b(t);
  b.increment();

を実行したとき, b.increment(); は TTest::increment を呼び出す(仮想関数).これが「動的結合」だ.ところが,このとき省略したパラメータとして使われるのは, TTest::increment のデフォルトパラメータ add=-1 ではなく, TBase::increment のデフォルトパラメータ add=1 なのだ. だから,

  TTest t;
  t.increment();
  cout<<"t.getX()= "<<t.getX()<<endl;
  TBase &b(t);
  b.increment();
  cout<<"b.getX()= "<<b.getX()<<endl;

を実行したとき,

t.getX()= -1
b.getX()= 0

という結果になる.これが「静的結合」である.

Scott Meyers (スコット・メイヤーズ): Effective C++, 吉川訳, アスキー出版局, 1998 によると,

38項 継承したデフォルトパラメータ値を再定義してはならない

とある.これを守らないと混乱を招くことは,上の例から理解できるだろう.

ひとつ付け加えると,デフォルトパラメータが静的に結合されるから, TTest::increment のデフォルトパラメータを省略すると上記の t.increment(); はコンパイルエラーとなることに注意しないとならない.継承したデフォルトパラメータを再定義しない方がよいが,継承先でもデフォルトパラメータを有効にしたい場合は,「同じデフォルトパラメータ」で関数を再定義する必要があるのである.




Last-modified:2014-12-30 (Tue) 20:08:56 (3836d)
Site admin: Akihiko Yamaguchi.
Written by: Akihiko Yamaguchi.
System: PukiWiki 1.5.0. PHP 5.2.17. HTML conversion time: 0.008 sec.