ページ 1 / 1
デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:08
by あまち
初めまして。
C++で導入された(と思っています)デフォルト引数について
疑問がありますので掲示板にて質問させていただきます。
C++では関数の多重定義が許されており、
また、クラスの実体(オブジェクト?)を作成したときに
実行されるコンストラクタも多重定義可能です。
ここで質問なのですが
引数が1つのコンストラクタを作成し、
引数が一つも与えられない場合はデフォルトの値を
使用するつもりでデフォルト引数としてコンストラクタを作成しました。
しかしいざコンパイルすると
コンストラクタに引数を与えるときはコンパイルに成功し、
コンストラクタに引数を与えないときはコンパイルに失敗します。
デフォルト引数のコーディング作法が悪いかと思い
コンストラクタではないメンバ関数を作成し確認しましたが、
うまく動作しています。
コンストラクタでは失敗し、メンバ関数では成功することから
コンストラクタではデフォルト引数を使用することができないのでしょうか?
またできるならどのような場合に使用することができるのでしょうか?
以上、ご教授お願い致します。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:14
by たかぎ
問題が再現するソースコードを補足してください。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:24
by あまち
たかぎ様
下記がソースとなります。
# 長くなりますのでコンストラクタとデストラクタ以外は削除しました。
main.cppは下記のとおりです。
#include <stdio.h>
#include "CQueue.h"
int main(void)
{
class CQueue CQ(); // NG
return 0;
}
CQueue.hは下記のとおりです。
class CQueue
{
protected:
WORD m_wQueueSize;
public:
CQueue(WORD wQueueSize = DEFAULT_QUEUE_SIZE);
~CQueue(void);
};
CQueue::CQueue(WORD wQueueSize)
{
m_wQueueSize = wQueueSize;
}
CQueue::~CQueue(void)
{
m_wQueueSize = 0;
}
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:26
by たかぎ
> class CQueue CQ(); // NG
↑は、引数を受け取らず、class CQueue型の返却値を返すCQ関数の宣言です。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:35
by あまち
たかぎ様
返信ありがとうございます。
>> class CQueue CQ(); // NG
> ↑は、引数を受け取らず、class CQueue型の返却値を返すCQ関数の宣言です。
関数の宣言としてコンパイラに認識されてしまうのですね・・・
本来私は引数がなかったらデフォルト引数を引数として
コンストラクタを実行してもらい、
引数があったらそれを引数として(日本語として変ですね)
コンストラクタを実行してもらいたかったのですが。
上記のような動作を実装したい場合は
コンストラクタを二つ用意するのが普通なのでしょうか?
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:44
by たかぎ
> コンストラクタを二つ用意するのが普通なのでしょうか?
いいえ。
CQueue CQ;
とします。CQueueの前のclassはあってもかまいませんが、括弧は取ってください。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 21:54
by あまち
たかぎ様
返信ありがとうございます。
>> コンストラクタを二つ用意するのが普通なのでしょうか?
> いいえ。
> CQueue CQ;
> とします。CQueueの前のclassはあってもかまいませんが、括弧は取ってください。
指摘のとおりに実装しましたらきちんとコンパイルが成功し
意図した通りの動作になりました。
デフォルト引数が設定されているメンバ関数では
Func( );
Func(1);
としても動作しますがコンストラクタは違うのですね。
まだ理解ができてませんが解決方法がわかり、
すっきりしました。
おかげで本件、解決することができました。
ご教授ありがとうございました。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 22:00
by たかぎ
> デフォルト引数が設定されているメンバ関数では
> Func( );
> Func(1);
> としても動作しますがコンストラクタは違うのですね。
一時オブジェクトを作る場合であれば、普通の関数と同じように、
CQueue()
CQueue(1)
とします。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月05日(木) 22:14
by あまち
たかぎ様
返信ありがとうございます。
> 一時オブジェクトを作る場合であれば、普通の関数と同じように
> CQueue()
> CQueue(1)
> とします。
上記は
CQueue CQ( ); // 引数としてデフォルト引数が設定されるはず
CQueue CQ(1); // 引数として1が設定される
ということでしょうか?
CQueue CQ( );
はコンパイルに失敗してしまいます。
先ほどたかぎ様に関数宣言とみなされるとコメントを頂きました。
普通の関すと同じように括弧も使用したいのですが
可能なのでしょうか?
何度も質問してしまい申し訳ございませんが
ご教授をお願い致します。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月06日(金) 00:53
by ドラ
>CQueue CQ( );
この文のトークンの並びをよく見てください。
型名 識別子( );
ですね?
このような順番にトークンが並んでいると、次のように解釈できる可能性があります。
・CQueue型の CQ という名前のインスタンスを引数なしで作ろうとしている。
・CQueue型を返す CQ という名前の引数をとらない関数のプロトタイプ宣言をしている。
こうなるとコンパイラにはどちらか判断できないので、
このような場合は、"宣言であるとみなす"というのがC++のルールです。
だから「CQueue CQ( );」という並びに限って
引数なしでCQueue型のインスタンスを構築するとは解釈してくれないのです。
(逆に言うとそれ以外ならOK)
>普通の関すと同じように括弧も使用したいのですが可能なのでしょうか?
CQueue CQ; で我慢してください。
Re:デフォルト引数とコンストラクタについて
Posted: 2009年11月07日(土) 02:32
by あまち
ドラ様
返信ありがとうございます。
> >普通の関すと同じように括弧も使用したいのですが可能なのでしょうか?
> CQueue CQ; で我慢してください。
了解しました。
またおかげで理解することができました、
たかぎ様、ドラ様のおかげで無事完全解決することができました。
ありがとうございました。