コンストラクタからインスタンスメソッドを呼び出す場合には下記のような
注意が必要ですが、そもそもそんな注意が必要な仕様にしてまで呼び出せる
ようにする必要があるのでしょうか?
単純に呼び出せないようにすれば良いのではないでしょうか?
■コンストラクタからのインスタンスメソッド呼び出しの注意
◇C++等の場合
メソッドがサブクラスでオーバーライドされていても、サブクラスの
メソッドではなく自クラスのメソッドが呼び出される。
◇Ruby,Java等の場合
メソッドがサブクラスでオーバーライドされている場合、サブクラスの
メソッドが呼び出されるが、サブクラスでのコンストラクトが完了して
いない可能性がある。
■例
◇C++の場合
・ソースプログラム
#include <string>
#include <iostream>
class SuperClass
{
std::string x_;
public:
SuperClass(const std::string &x):
x_(x)
{
method();
}
virtual ~SuperClass() {}
virtual void method() const {
std::cout << "in SuperClass#method\n";
std::cout << x_ << "\n";
}
};
class SubClass: public SuperClass
{
std::string y_;
public:
SubClass(const std::string &y):
SuperClass(y),
y_(y + "def")
{
}
virtual ~SubClass() {}
virtual void method() const {
std::cout << "in SubClass#method\n";
std::cout << y_ << "\n";
}
};
int main()
{
SubClass obj("abc");
obj.method();
}
・実行結果
in SuperClass#method
abc
in SubClass#method
abcdef
◇Rubyの場合
・ソースプログラム
#/usr/local/bin/ruby
class SuperClass
def initialize(x)
@x = x
method()
end
def method
puts 'in SuperClass#method'
puts @x
end
end
class SubClass < SuperClass
def initialize(y)
super(y)
@y = y + 'def'
end
def method
puts 'in SubClass#method'
puts @y
end
end
obj = SubClass.new('abc')
obj.method
・実行結果
in SubClass#method
nil
in SubClass#method
abcdef
--
pegacorn
C++使いの意見ですが、
記事 <1173408799....@30g2000cwc.googlegroups.com> で
"pegacorn"さんは書きました
> コンストラクタからインスタンスメソッドを呼び出す場合には下記のような
> 注意が必要ですが、そもそもそんな注意が必要な仕様にしてまで呼び出せる
> ようにする必要があるのでしょうか?
> 単純に呼び出せないようにすれば良いのではないでしょうか?
引数の異なる複数のコンストラクタがある場合に、それぞれのコンストラクタに
いちいち初期化コードを記述するのは無駄が多いし保守性が悪くなるので、
共通の初期化ルーチンはメソッドとして用意して、それぞれのコンストラクタから
呼び出す、ということはよくやってます。
例えば、メンバ変数が増えたりした時に、全てのコンストラクタにそのメンバの
初期化コードを書くのは手間がかかりますし、ヘタすると初期化ミスの元ですし。
あまり良い例かわかりませんが、
class array {
int *p;
int s;
init() { p = NULL; s = 0; }
destroy() { delete [] p; }
alloc(int size) { destroy(); p = new int[s = size];}
copy(const aclass &src) { alloc(src.s); memcpy(p, src.p, sizeof(*p)*s);}
public:
array() {init();}
array(int size) {init(); alloc(size);}
array(const array &src) {init(); copy(src);}
~array() { destroy(); }
array &operator=(const array &src) { copy(src); return *this;}
};
みたいな感じ。それぞれの機能を書き下すより効率は悪くなってますが、
それよりも保守性重視ってことで。
PROJECT TEAM DoGA 高津正道 ta...@doga.jp
PROJECT TEAM DoGAのホームページ → http://doga.jp/
3月9日(金) 今日のマーフィーの法則 [収支力学の第1法則]
思いがけない収入があると、思いがけない同額の支出がある。
私も時々やってました。
でも、それってこの件の典型的なはまりパターンではないでしょうか?
・ソースプログラム
#include <string>
#include <iostream>
class SuperClass
{
std::string x_;
public:
SuperClass()
{
initialize();
}
virtual ~SuperClass() {}
virtual void initialize() {
x_ = "abc";
}
virtual void put_property() const {
std::cout << "x_ = " << x_ << "\n";
}
};
class SubClass: public SuperClass
{
std::string y_;
public:
SubClass():
SuperClass()
{
}
virtual ~SubClass() {}
virtual void initialize() {
SuperClass::initialize();
y_ = "def";
}
virtual void put_property() const {
SuperClass::put_property();
std::cout << "y_ = " << y_ << "\n";
}
};
int main()
{
SubClass obj;
obj.put_property();
std::cout << "----\n";
obj.initialize();
obj.put_property();
}
・実行結果
x_ = abc
y_ =
----
x_ = abc
y_ = def
--
pegacorn
http://slashdot.jp/developers/article.pl?sid=06/12/14/1233207
楽しいですか?
http://slashdot.jp/developers/article.pl?sid=06/12/14/1233207