Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

コンストラクタからのインスタンスメソッドの呼び出しは必要か?

8 views
Skip to first unread message

pegacorn

unread,
Mar 8, 2007, 9:53:19 PM3/8/07
to
こんにちは。コンストラクタに関して教えてください。

コンストラクタからインスタンスメソッドを呼び出す場合には下記のような
注意が必要ですが、そもそもそんな注意が必要な仕様にしてまで呼び出せる
ようにする必要があるのでしょうか?
単純に呼び出せないようにすれば良いのではないでしょうか?


■コンストラクタからのインスタンスメソッド呼び出しの注意
◇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

Masamichi Takatsu

unread,
Mar 8, 2007, 10:41:16 PM3/8/07
to
たかつです。

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法則]
思いがけない収入があると、思いがけない同額の支出がある。

pegacorn

unread,
Mar 9, 2007, 8:26:41 AM3/9/07
to
On 3月9日, 午後12:41, Masamichi Takatsu <t...@doga.jp> wrote:
> 引数の異なる複数のコンストラクタがある場合に、それぞれのコンストラクタに
> いちいち初期化コードを記述するのは無駄が多いし保守性が悪くなるので、
>
> 共通の初期化ルーチンはメソッドとして用意して、それぞれのコンストラクタから
> 呼び出す、ということはよくやってます。

私も時々やってました。
でも、それってこの件の典型的なはまりパターンではないでしょうか?

・ソースプログラム
#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

pegacorn

unread,
May 17, 2007, 7:36:59 AM5/17/07
to
On 5月17日, 午前10:03, k...@ie.u-ryukyu.ac.jp (Shinji KONO) wrote:
> ま、今は、Java に逃げるという手があるから、まだまし。ってい
> うか、今時、C++を使うのは、Windows な開発者だけだろ?

http://slashdot.jp/developers/article.pl?sid=06/12/14/1233207

pegacorn

unread,
May 17, 2007, 8:29:32 AM5/17/07
to
On 5月17日, 午前10:03, k...@ie.u-ryukyu.ac.jp (Shinji KONO) wrote:
> ま、今は、Java に逃げるという手があるから、まだまし。ってい
> うか、今時、C++を使うのは、Windows な開発者だけだろ?

楽しいですか?
http://slashdot.jp/developers/article.pl?sid=06/12/14/1233207

0 new messages