電子書籍の厳選無料作品が豊富!

デフォルト引数は、関数の宣言部、または定義部の
いずれかで与えることができると思うのですが、
VC6sp6で
+-------------------------------+
class tmp{
int m_x;
public:
tmp(int x);
};
tmp::tmp(int x=0) : m_x(x){}
+-------------------------------+
とすると、「デフォルトコンストラクタがない」と、エラーになります。
(因みにBCC551ではコンパイルできます)
また、デフォルトコンストラクタを追加すると、
「オーバーロード関数の呼び出しが解決できない」というエラーになります。
前者のエラーの原因は、コンパイラ エラー C2512を読めば理解できますし、
後者の言うことも納得できます。
ここで疑問です。
(1) デフォルト引数はどこで与えることができるか?
(2) デフォルトコンストラクタは、ユーザ定義コンストラクタがある場合は、
必ず用意しなければならないか?(エラーc2512)

C++の規格ではどうなっているのでしょうか?
よろしくお願いします。

A 回答 (2件)

手元にあるのはARMの1版なのですが、ご容赦を。



8.2.6
デフォルト引数は宣言時に指定することが可能です。
#コンパイル結果からは、おっしゃるとおり定義時でも有効になりそうなのですが、記述を見つけられませんでした。
12.1
デフォルトコンストラクタは、コンストラクタが何も宣言されてないときにのみ(必要ならば)生成される。

サンプルソースでは、引数ありのコンストラクタが宣言されていますので、デフォルトコンストラクタは生成されません。
しかし、VC6は定義部のデフォルト引数を有効とみなしたらしく、その結果引数なしの関数が存在し、デフォルトコンストラクタを定義すると、引数なしの関数が2つとなり、オーバーロード関数の呼び出し解決ができなくなったようです。
ARMにも、デフォルト引数を得た結果として、デフォルトコンストラクタとなるということを判断するために、コンパイラに賢くなることを求めている、と記述されていますので、やや賢さが足りなくて、混乱しているのではないでしょうか?

BCC551は、定義部のデフォルト引数から、デフォルトコンストラクタ(引数なしのコンストラクタ)が存在すると認識したと予想されます。
    • good
    • 0

> デフォルト引数は、関数の宣言部、または定義部の


> いずれかで与えることができると思うのですが、

違います。

> (1) デフォルト引数はどこで与えることができるか?

それを呼ぶ側が知っていなくてはならないので、宣言部です。

> (2) デフォルトコンストラクタは、ユーザ定義コンストラクタがある場合は、必ず用意しなければならないか?

いいえ。'必要に応じて' です。
    • good
    • 0
この回答へのお礼

デフォルト引数は宣言部で指定する、ということがキモだと思いました。

(2)はアホな質問でした。
インスタンス生成時に、そのインスタンスに対応するコンストラクタがない場合に、C2512のエラーになるということですね。
デフォルトコンストラクタは関係なかったです。
混乱してました。

+-----------------------------+
class tmp{
int m_x;
public :
tmp(int x = 0);
};
tmp::tmp(int x) : m_x(x) { }
+-----------------------------+
が正しい記述ですね。

お二方、返事が遅くなりましたが、
ありがとうございました。

お礼日時:2004/08/27 19:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!