デフォルト引数とコンストラクタについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
あまち

デフォルト引数とコンストラクタについて

#1

投稿記事 by あまち » 15年前

初めまして。
C++で導入された(と思っています)デフォルト引数について
疑問がありますので掲示板にて質問させていただきます。

C++では関数の多重定義が許されており、
また、クラスの実体(オブジェクト?)を作成したときに
実行されるコンストラクタも多重定義可能です。
ここで質問なのですが
引数が1つのコンストラクタを作成し、
引数が一つも与えられない場合はデフォルトの値を
使用するつもりでデフォルト引数としてコンストラクタを作成しました。
しかしいざコンパイルすると
コンストラクタに引数を与えるときはコンパイルに成功し、
コンストラクタに引数を与えないときはコンパイルに失敗します。
デフォルト引数のコーディング作法が悪いかと思い
コンストラクタではないメンバ関数を作成し確認しましたが、
うまく動作しています。

コンストラクタでは失敗し、メンバ関数では成功することから
コンストラクタではデフォルト引数を使用することができないのでしょうか?
またできるならどのような場合に使用することができるのでしょうか?

以上、ご教授お願い致します。

たかぎ

Re:デフォルト引数とコンストラクタについて

#2

投稿記事 by たかぎ » 15年前

問題が再現するソースコードを補足してください。

あまち

Re:デフォルト引数とコンストラクタについて

#3

投稿記事 by あまち » 15年前

たかぎ様
下記がソースとなります。
# 長くなりますのでコンストラクタとデストラクタ以外は削除しました。

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:デフォルト引数とコンストラクタについて

#4

投稿記事 by たかぎ » 15年前

> class CQueue CQ(); // NG

↑は、引数を受け取らず、class CQueue型の返却値を返すCQ関数の宣言です。

あまち

Re:デフォルト引数とコンストラクタについて

#5

投稿記事 by あまち » 15年前

たかぎ様
返信ありがとうございます。

>> class CQueue CQ(); // NG
> ↑は、引数を受け取らず、class CQueue型の返却値を返すCQ関数の宣言です。
関数の宣言としてコンパイラに認識されてしまうのですね・・・
本来私は引数がなかったらデフォルト引数を引数として
コンストラクタを実行してもらい、
引数があったらそれを引数として(日本語として変ですね)
コンストラクタを実行してもらいたかったのですが。
上記のような動作を実装したい場合は
コンストラクタを二つ用意するのが普通なのでしょうか?

たかぎ

Re:デフォルト引数とコンストラクタについて

#6

投稿記事 by たかぎ » 15年前

> コンストラクタを二つ用意するのが普通なのでしょうか?

いいえ。

CQueue CQ;

とします。CQueueの前のclassはあってもかまいませんが、括弧は取ってください。

あまち

Re:デフォルト引数とコンストラクタについて

#7

投稿記事 by あまち » 15年前

たかぎ様
返信ありがとうございます。

>> コンストラクタを二つ用意するのが普通なのでしょうか?
> いいえ。
> CQueue CQ;
> とします。CQueueの前のclassはあってもかまいませんが、括弧は取ってください。
指摘のとおりに実装しましたらきちんとコンパイルが成功し
意図した通りの動作になりました。
デフォルト引数が設定されているメンバ関数では
Func( );
Func(1);
としても動作しますがコンストラクタは違うのですね。
まだ理解ができてませんが解決方法がわかり、
すっきりしました。

おかげで本件、解決することができました。
ご教授ありがとうございました。

たかぎ

Re:デフォルト引数とコンストラクタについて

#8

投稿記事 by たかぎ » 15年前

> デフォルト引数が設定されているメンバ関数では
> Func( );
> Func(1);
> としても動作しますがコンストラクタは違うのですね。

一時オブジェクトを作る場合であれば、普通の関数と同じように、

CQueue()
CQueue(1)

とします。

あまち

Re:デフォルト引数とコンストラクタについて

#9

投稿記事 by あまち » 15年前

たかぎ様
返信ありがとうございます。

> 一時オブジェクトを作る場合であれば、普通の関数と同じように
> CQueue()
> CQueue(1)
> とします。
上記は
CQueue CQ( ); // 引数としてデフォルト引数が設定されるはず
CQueue CQ(1); // 引数として1が設定される
ということでしょうか?
CQueue CQ( );
はコンパイルに失敗してしまいます。
先ほどたかぎ様に関数宣言とみなされるとコメントを頂きました。
普通の関すと同じように括弧も使用したいのですが
可能なのでしょうか?
何度も質問してしまい申し訳ございませんが
ご教授をお願い致します。

ドラ

Re:デフォルト引数とコンストラクタについて

#10

投稿記事 by ドラ » 15年前

>CQueue CQ( );
この文のトークンの並びをよく見てください。

型名 識別子( );

ですね?
このような順番にトークンが並んでいると、次のように解釈できる可能性があります。

・CQueue型の CQ という名前のインスタンスを引数なしで作ろうとしている。
・CQueue型を返す CQ という名前の引数をとらない関数のプロトタイプ宣言をしている。

こうなるとコンパイラにはどちらか判断できないので、
このような場合は、"宣言であるとみなす"というのがC++のルールです。
だから「CQueue CQ( );」という並びに限って
引数なしでCQueue型のインスタンスを構築するとは解釈してくれないのです。
(逆に言うとそれ以外ならOK)


>普通の関すと同じように括弧も使用したいのですが可能なのでしょうか?
CQueue CQ; で我慢してください。

あまち

Re:デフォルト引数とコンストラクタについて

#11

投稿記事 by あまち » 15年前

ドラ様
返信ありがとうございます。

> >普通の関すと同じように括弧も使用したいのですが可能なのでしょうか?
> CQueue CQ; で我慢してください。
了解しました。
またおかげで理解することができました、


たかぎ様、ドラ様のおかげで無事完全解決することができました。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る