【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.19812

引数と関数の実体の間に:(コロン)
投稿者---だん(2005/02/10 11:35:57)


以下のソースは分からない部分の抜粋です。
template<
class bbb = std::ofstream
>
class aaa
{
bbb & ccc;
public:
// コンストラクタ
aaa(
bbb & ddd
)
: ccc( ddd )
{
aaa();
}
}

わからない部分はaaaのコンストラクタです。
通常コンストラクタは
aaa(...)
{
...
}
となると思うのですが、
上記では引数と関数の実体の間に:(コロン)が
入っているのです。
そこが理解できていません。
:(コロン)を調べたところスコープという言葉を
目にして読んでみましたが、やはり理解できていません。

皆様、ご助力ください。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:引数と関数の実体の間に:(コロン) 19814 επιστημη 2005/02/10 12:01:03


No.19814

Re:引数と関数の実体の間に:(コロン)
投稿者---επιστημη(2005/02/10 12:01:03)


>上記では引数と関数の実体の間に:(コロン)が
>入っているのです。
>そこが理解できていません。
>:(コロン)を調べたところスコープという言葉を
>目にして読んでみましたが、やはり理解できていません。

それはスコープではありません。'メンバ初期化子'です。

コンストラクタ(引数...) : メンバ(初期値) {
 // なにかする
}

と書くことで、メンバを初期値でコンストラクトします。



この投稿にコメントする

削除パスワード

No.19816

Re:引数と関数の実体の間に:(コロン)
投稿者---だん(2005/02/10 13:18:12)


ありがとうございます。

>コンストラクタ(引数...) : メンバ(初期値) {
> // なにかする
>}
>

自分でも調べてみますが

'メンバ初期化子'は
・コンストラクタの引数とコンストラクタの関数の実体の間でしか使用できないのですか?
・コンストラクタの中でコンストラクタをコールするのと同じですか?
・もし同じ場合はどちらを使うのが普通でしょうか?

以上、すいませんがご助力御願いします。



この投稿にコメントする

削除パスワード

No.19817

Re:引数と関数の実体の間に:(コロン)
投稿者---επιστημη(2005/02/10 14:58:12)


>'メンバ初期化子'は
>・コンストラクタの引数とコンストラクタの関数の実体の間でしか使用できないのですか?
それ以外のところで使用してみればわかる。

>・コンストラクタの中でコンストラクタをコールするのと同じですか?
コンストラクタの中でコンストラクタを呼んでみればわかる。



この投稿にコメントする

削除パスワード

No.19857

Re:引数と関数の実体の間に:(コロン)
投稿者---だん(2005/02/11 23:05:51)


>>'メンバ初期化子'は
>>・コンストラクタの引数とコンストラクタの関数の実体の間でしか使用できないのですか?
>それ以外のところで使用してみればわかる。
その後いろいろ調べて、上記以外でも使用できると理解しました。
間違ってたらご指摘ください。

>>・コンストラクタの中でコンストラクタをコールするのと同じですか?
>コンストラクタの中でコンストラクタを呼んでみればわかる。
いろいろやってみようと思い、
:の行をコメントにしてみたところ
コンパイルエラーがでてしまいました。
コンパイラ エラー C2758
'const' : オブジェクト コンストラクタの初期化リストで初期化されませんでした。
constデータを使っているつもりもありませんし、
理解できません。

ネットでメンバ初期化子を調べても数件しかヒットしなく
近くの本屋でもメンバ初期化子が掲載されている本を
探したのですが、見つからず手詰まり状態です。
ご助力ください。




この投稿にコメントする

削除パスワード

No.19860

Re:引数と関数の実体の間に:(コロン)
投稿者---RAPT(2005/02/12 04:42:35)


メンバ初期化子は、

class CHogeClass : public CFooClass
{
    int a;
    const int b;
public:
    CHogeClass(HWND hWndParent = NULL) : CFooClass(hWndParent), a(0), b(100)
    {
    }
};

などのように、コンストラクタでしか記述できません。
「(厳密な意味での)初期化」はここでしか書けません。

# ベースクラスのコンストラクタ呼び出しやconst変数の初期化などは
# 個々以外に記述できません。コンストラクタの{}内で記述する事は
# 「(厳密な意味での)初期化」とはなりません。

※コンストラクタでメンバ初期化子をどのような順序で指定しても、
メンバが初期化される順序は変わりません。
メンバは、クラスで宣言された順に初期化されます。



この投稿にコメントする

削除パスワード

No.19875

Re:引数と関数の実体の間に:(コロン)
投稿者---だん(2005/02/12 17:09:13)


「メンバ初期化子は、コンストラクタでしか記述できない」
ですね、わかりました。

class CHogeClass : public CFooClass
{
    int a;
    const int b;
public:
    CHogeClass(HWND hWndParent = NULL) : CFooClass(hWndParent), a(0), b(100)
    {
    }
};
の場合、コンストラクタが実行される前に
CFooClass = hWndParent; (意味がわかってません)
a = 0;
b = 100;
が実行されるという認識でよろしいのでしょうか。

class CHogeClass : public CFooClass
{
    const int a = 0;
    const int b = 100;
public:
    CHogeClass(HWND hWndParent = NULL) : CFooClass(hWndParent)
    {
    }
};
と
class CHogeClass : public CFooClass
{
    int a;
    const int b;
public:
    CHogeClass(HWND hWndParent = NULL) : CFooClass(hWndParent), a(0), b(100)
    {
    }
};
を比べた場合の、メンバ初期化子の利点を知りたいのですが




この投稿にコメントする

削除パスワード

No.19876

Re:引数と関数の実体の間に:(コロン)
投稿者---ぽへぇ(2005/02/12 18:08:41)



>CFooClass = hWndParent; (意味がわかってません)
CHogeClass は CFooClass の継承なのはわかる?
CFooClass のコンストラクタ呼び出し時に hWndParent を引数にすると
いうこと。

>を比べた場合の、メンバ初期化子の利点を知りたいのですが

1番目ですが、
>    const int a = 0;
>    const int b = 100;
私は不勉強なのでわかりませんが、こんな書き方ができる
コンパイラがあるんですか?
(少なくとも VC++7.1ではできませんでした。
 static const intならわかりますがね)




この投稿にコメントする

削除パスワード

No.19882

Re:引数と関数の実体の間に:(コロン)
投稿者---RAPT(2005/02/13 00:41:26)


typo
> # 個々以外に記述できません。
# ここ以外に記述できません。


> の場合、コンストラクタが実行される前に
> CFooClass = hWndParent; (意味がわかってません)
> a = 0;
> b = 100;
> が実行されるという認識でよろしいのでしょうか。

CFooClass(hWndParent)
で呼び出した場合、CFooClass(HWND)のコンストラクタを呼びます。

> CFooClass = hWndParent;
このような書き方はできません。インスタンスが宣言されていないので。
CFooClassのインスタンスで、かつoperator=がオーバーライドされていればOKですが。

ま、ありていに言うと、
class CHogeClass
{
    int a;
    CHogeClass() : a(0)
    {
    }
};
での a の初期化は、
int a = 0;
による初期化と同等と思ってOKです。

class CHogeClass
{
    int a;
    CHogeClass()
    {
        a = 0;
    }
};
この場合は、
int a;
a = 0;
と同等で、宣言時は明示的な初期化をせず、次で代入演算子を呼び出しています。


処理の順番としては、初期化子が評価された後に、コンストラクラの{}内が処理されます。


> class CHogeClass : public CFooClass
> {
>     const int a = 0;
>     const int b = 100;

C++では、そのような記述はできません。
# Javaはできるけど。

また、static const int だとしても、クラスの定義の外に書く必要があります。
class CHogeClass
{
public:
    static const int a;
};
const int CHogeClass::a = 0;

いずれにしろ、クラス定義内でメンバ変数の宣言同時初期化を1行で書くことはできません。




この投稿にコメントする

削除パスワード

No.19883

Re:引数と関数の実体の間に:(コロン)
投稿者---Ban(2005/02/13 01:48:37)


> また、static const int だとしても、クラスの定義の外に書く必要が
> あります。
 -- snip --
> いずれにしろ、クラス定義内でメンバ変数の宣言同時初期化を1行で
> 書くことはできません。

VC6の時代はそうでしたが、今の規格では static const int を外に
書く必要はありません。VC7.1 とか g++ とかはちゃんと通るように
なってます。


この投稿にコメントする

削除パスワード

No.19884

Re:引数と関数の実体の間に:(コロン)
投稿者---RAPT(2005/02/13 04:40:35)


>> また、static const int だとしても、クラスの定義の外に書く必要が
>> あります。
> -- snip --
>> いずれにしろ、クラス定義内でメンバ変数の宣言同時初期化を1行で
>> 書くことはできません。
>
>VC6の時代はそうでしたが、今の規格では static const int を外に
>書く必要はありません。VC7.1 とか g++ とかはちゃんと通るように
>なってます。
あ、そうなんだ。当方、未だにVC++6です。
いいなー。そういった細かい辺り、移行したくなるなぁ。

フォローありがとうございます。


この投稿にコメントする

削除パスワード

No.19890

Re:引数と関数の実体の間に:(コロン)
投稿者---とおりすがり(2005/02/13 16:12:58)


>>VC6の時代はそうでしたが、今の規格では static const int を外に
>>書く必要はありません。VC7.1 とか g++ とかはちゃんと通るように
>>なってます。

すみません。
これって、C++の規格としてOKになったということですか?
VC6が古い規格に準拠してるってこと?


この投稿にコメントする

削除パスワード

No.19893

Re:引数と関数の実体の間に:(コロン)
投稿者---Ban(2005/02/13 17:11:48)


>これって、C++の規格としてOKになったということですか?
>VC6が古い規格に準拠してるってこと?

少なくとも ISO/IEC 14882:1998 時点から言語規格としてOKです。
# 現在の規格については、www.jisc.go.jp あたりで
# JISX3014(ISO/IEC 14882:2003) の 9.4.2 の 4 を参照。

単に、既存実装の処理系が制定された標準規格に準拠しきれなかった
ものと思っていますが、どの時点のドラフトから盛り込まれたものか、
規格確定以前に許されなかったのか否かについては把握できてません。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧