オーバライド関数について質問があります。
以下のようなクラスAとBがあります。
クラスAは基本クラスです。
クラスBはクラスAから導出しました。
------------------------------------
CLASS A
{
public:
virtual void func(char* p, ...);
}
------------------------------------
CLASS B : public A
{
public:
void func(char* p, ...);
}
------------------------------------
メンバ関数の func() はオーバライド関数で、可変長の引数を持っています。

今、クラスBの func() の中で、クラスAの func() をコールするようにコーディングしました。
-----------------------------------
void B::func(char* p, ...)
{
:
:

A::func( ???? )

:
:
}
-----------------------------------
ところが、クラスBの func()が受け取った引数を、そのままクラスAの func() に渡したいのですが、どうしたらいいのか分かりません。これって無理でしょうか?

教えて下さい。

A 回答 (1件)

私は詳しくないですが、別のメーリングリストで過去に同様の議論


がされています。このアーカイブがちょっと大きいのですが、
参考URLのところから、
「可変引数をもつ仮想関数のオーバーライド方法について」という
記事(番号7433)を探してみてください。
結果としては、難しそうな雰囲気です。

参考URL:http://venus13.aid.kyushu-id.ac.jp/ml-arc/builde …
    • good
    • 0

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

このQ&Aと関連する良く見られている質問

Qc++11での文字列リテラルの特殊化について

c++11言語でのテンプレート部分特殊化についての質問です。

コメントアウト部分は出力結果です

template<class T> struct VT { static const int type = 1;};
template<class T,int N> struct VT< T[N] > { static const int type = 2;};
template<class T,int N> struct VT< const T[N] > { static const int type = 3;};
template<class T> struct VT< T* > { static const int type = 4;};
template<class T> struct VT< const T*const > { static const int type = 5;};
#include<iostream>
#include<typeinfo>
int main(){
std::cout<<"A:"<< VT< char >::type << std::endl; // A:1
std::cout<<"B:"<< VT< char[10] >::type << std::endl; // B:2
std::cout<<"C:"<< VT< char* >::type << std::endl; // C:4
std::cout<<"D:"<< VT< char const [1] >::type << std::endl; // D:3
std::cout<<"E:"<< VT< decltype("") >::type << std::endl; // E:1
std::cout<<"G:"<< typeid( char const [1] ).name() << std::endl;// G:char const [1]
std::cout<<"H:"<< typeid( "" ).name() << std::endl;// H:char const [1]
}

型名を直接記述したD,G、文字列リテラルを記述したE,H。
コンパイラ毎の差はあれど、GとHの型名は同じものが表示されます。
ですが、[D:3] [E:1]と値は違い、別の特殊化テンプレートが使われています。
この部分が分かりません。

また、配列リテラル、文字列リテラルに対し部分特殊化テンプレートを宣言する方法などありましたら、ご教示お願いします。

c++11言語でのテンプレート部分特殊化についての質問です。

コメントアウト部分は出力結果です

template<class T> struct VT { static const int type = 1;};
template<class T,int N> struct VT< T[N] > { static const int type = 2;};
template<class T,int N> struct VT< const T[N] > { static const int type = 3;};
template<class T> struct VT< T* > { static const int type = 4;};
template<class T> struct VT< const T*const > { stati...続きを読む

Aベストアンサー

文字列リテラルが decltype で参照になるってことは, 参照に対する部分特殊化すればいい. 例えば
template <class T> struct VT<T &> { /* 省略 */ };
で参照に対する部分特殊化ができると思う. さらに配列に対しても部分特殊化したければ
template <class T, int N> struct VT<T (&)[N]> { /* 省略 */ };
とかでいいんじゃないかな.

Qvoid main(void){...}だとDosWindowが開くので

わざわざWindowsアプリにして以下のようにするしかないのでしょうか?

LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP)
{
//ここに宣言を置く
switch(wM)
{
case WM_CREATE:
//ここに処理を置く
return 0;
default:
return(DefWindowProc(hW,wM,wP,lP));
}
}
WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS)
{
WNDCLASSwc;
HWNDhW,hPW;
MSGms;

wc.lpszClassName="goo";
wc.lpfnWndProc=(WNDPROC)WinProcedure;
wc.hInstance=hI;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.cbClsExtra=NULL;
wc.cbWndExtra=NULL;
wc.hIcon=LoadIcon(NULL,IDI_EXCLAMATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName=NULL;
RegisterClass(&wc);
hW=CreateWindow
(
"goo",
"教えて!goo",
WS_OVERLAPPED,
0,
0,
640,
456,
NULL,
NULL,
hI,
NULL
);
ShowWindow(hW,nCS);
UpdateWindow(hW);
while(GetMessage(&ms,NULL,NULL,NULL))
{
TranslateMessage(&ms);
DispatchMessage(&ms);
}
return (ms.wParam);
}

もっと簡単にDosWindowが開かないようにする方法はないのでしょうか?
もしないとすると上記記述でもっと簡単にできないでしょうか?

わざわざWindowsアプリにして以下のようにするしかないのでしょうか?

LONG WINAPI WinProcedure(HWND hW,UINT wM,UINT wP,LONG lP)
{
//ここに宣言を置く
switch(wM)
{
case WM_CREATE:
//ここに処理を置く
return 0;
default:
return(DefWindowProc(hW,wM,wP,lP));
}
}
WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS)
{
WNDCLASSwc;
HWNDhW,hPW;
MSGms;

wc.lpszClassName="goo";
wc.lpfnWndProc=(WNDPROC)WinProcedure;
wc.hInstance=hI;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc...続きを読む

Aベストアンサー

ウィンドウを開く必要がないなら、mainをWinMainに変更するだけで良いのでは? ウィンドウクラス登録、ウィンドウ作成、メッセージループ、ウィンドウプロシージャは全て不要な気がしますが。

WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int nCS)
{
  //処理内容

  return 0;
}

Qregex関数を理解するには、何を説明すればよいか?

unixを使っているゼミにいます。c言語でregex関数の使い方や仕組みをゼミで発表しないといけないのですが、manのregcomp()やregexec()の解説を読んでも、
人に説明できるほどわかりません。まずregex関数を説明する上で、何を最初に説明すればいいでしょうか?
また、regcomp()などの関数のソースファイルなどがありましたら、教えてください。

Aベストアンサー

regex 使用例であれば、Google に regex、regcomp、regexec などのキー
ワードを入れて検索してみるだけでも結構見つかります。

中でも以下は比較的わかりやすく解説されているように思います。

http://sometime.minidns.net/~ccgi/posix_regex.html

> また、regcomp()などの関数のソースファイルなどがありましたら、教えてください。

http://ftp.gnu.org/glibc/

glibc (最新バージョンは 2.7) のソースコードを展開すると posix とい
うディレクトリがあるので、そこに regex のソースコードがあります。

ただし、非常に難解です。アルゴリズムなども含めて知る必要があるので
あれば、NFA や DFA というキーワードでも調べてみるとよいでしょう。

http://www2.starcat.ne.jp/~fussy/algo/algo7-5.htm

Qvoid func( void )について

void func( void )について

右側のvoidは引数がないという事は分かったのですが左側の
voidの意味は「値を返さないreturn型に用いる」とあったのですが
値を返さないreturnは使う意味はあるのでしょうか?
またどういった時に使うのでしょうか??

あと return 0 と return の違いは何なのでしょうか??

ご教授よろしくお願いいたします。

Aベストアンサー

#2,4です。
C言語には必ず最初に起動されるmainという名前の特別な関数が必要です。
前回書いた関数は関数名がfuncのため、「最初に起動される関数がないよー」とのことでコンパイルエラーがでます。

というわけで、以下のように変えていただければ良いと思います。(全角スペース入れてないです)

#include <stdio.h>

void func(int n){
int i = 1;
int sum = 0;
if( n <= 0 )
{

printf( "1以上の値を指定してください\n" );
return;
}

while( i <= n )
{
sum += i;
i++;
}
printf( "結果は%dです\n", sum );
}

int main(){
func();

return 0;
}


main関数はint型の値を返すのが好ましいとされているので何らかの値を返そうということで0(エラーがないという意味かな)を返すのがほとんどです。慣例と思っていただいても良いと思います。
もちろん、他の関数は値を返す必要がなければ、
void func(void)のように定義してやればいいです。

#2,4です。
C言語には必ず最初に起動されるmainという名前の特別な関数が必要です。
前回書いた関数は関数名がfuncのため、「最初に起動される関数がないよー」とのことでコンパイルエラーがでます。

というわけで、以下のように変えていただければ良いと思います。(全角スペース入れてないです)

#include <stdio.h>

void func(int n){
int i = 1;
int sum = 0;
if( n <= 0 )
{

printf( "1以上の値を指定してください\n" );
return;
}

while( i <= n )
{
sum += i;
i++; ...続きを読む

Q正規表現(regex)でパラメータ付き文字列を置換したい

あるページ内に次のようなjavascriptがあるとします。
javascript:test(1);
javascript:test(2);
javascript:test(3);
javascript:test(4);

これらを次のように一度に置換したいわけです。

test_1.txt
test_2.txt
test_3.txt
test_4.txt

正規表現で置換するスクリプトを作っていますが、3行目の書き方をどうしていいかで困っています。
アドバイスお願いいたします。


---- スクリプトサンプル -------
Set regEx = New RegExp
regEx.pattern = "javascript:test\(.*\);"
repStr = 「この記述方法がわからない」

Do Until inFile.AtEndOfStream
tempLine = inFile.ReadLine
repLine = regEx.Replace(tempLine, repStr)
outFile.WriteLine repLine
Loop

あるページ内に次のようなjavascriptがあるとします。
javascript:test(1);
javascript:test(2);
javascript:test(3);
javascript:test(4);

これらを次のように一度に置換したいわけです。

test_1.txt
test_2.txt
test_3.txt
test_4.txt

正規表現で置換するスクリプトを作っていますが、3行目の書き方をどうしていいかで困っています。
アドバイスお願いいたします。


---- スクリプトサンプル -------
Set regEx = New RegExp
regEx.pattern = "javascript:test\(.*\);"
repStr = 「こ...続きを読む

Aベストアンサー

regEx.pattern = "javascript:test\((.*)\);

として、

repStr = "test_$1.txt"

としてみてください。
パターン中で()を使うと、()の中にマッチしたものを$1,$2などで後方参照できます。

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Qmb_regex_encodingでエンコードエラーが出ます

お世話になります。
フォームから投稿された時に文字をチェックする物を作成しております
----------------
<?php
function allHiragana($form_name, $err_name) {
mb_regex_encoding("Shift_JIS");
if(!mbereg('^[あ-んが-ぼぁ-ょゎっー]+$', $_POST[$form_name])) {
return $err_name. 'はひらがなで入力してください<br />';
}
}
?>
------------------------------------------------
このようなソースなのですが
三行目にこのようなエラーが出ます
Fatal error: Call to undefined function mb_regex_encoding() in
グーグル先生に質問してみたのですがイマイチ欲しい情報を得られなかった為質問させていただきます。
よろしくお願いします。

Aベストアンサー

エラーメッセージは「mb_regex_encodingという関数が未定義ですよ」と言っています。
環境が不明のため詳しいことは分かりかねますが、マルチバイト関連の関数が有効になってないものと思われます。

Q「void ( *signal(int sig, void (*func)(int)) ) (int)」の (int)

signal関数の書式についてですが、

  void ( *signal(int sig, void (*func)(int)) ) (int);

最後に付く(int)は一体何でしょうか?
このような関数の書式ははじめて見ました。
UNIX系の何かでしょうか。
回答よろしくお願いします。

Aベストアンサー

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換えると
void (*A)(int);
となり、Aを戻すと
void (*signal(int signum, void (*sighandler)(int)))(int);
となる。
)

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換...続きを読む

Q「?」の入った文字列置換を、RegEx.Replaceで行いたい

WSHを使い、あるhtmファイルの中にある特定の文字列を、RegEx.Replaceを使って置換しようとしています。通常の文字列置換についてはなんとか成功しているのですが、下記のケースで壁に当たっています。前に進める為にはどうしたらよいか、ヒントをご存知の方がいれば大変有り難く思います。

今回作業の特徴としては
1)置換前の文字列の中にメタキャラ「?」が含まれており、
2)置換前の文字列は、DBから読み込んできた文字列である
の2点です。(ちなみに1だけでは成功しているのですが、1と2が組み合わさると上手くいきません)

具体的には、下記のサンプルで置換前の文字列を
url_before = "test.asp\?param=999" (?についてはエスケープ文字付与)
のように明示的に書いてやると置換に成功しました。ところがDBから取得してきた文字列で置換をしようとしても失敗となります。
たとえばrs.fields("item")の中身が"test.asp?param=999"だったとして、先ほどの箇所を
url_before = replace(rs.fields("item"), "?", "\?")
とすると、置換されないのです。

'----- サンプル -----
Set fso = CreateObject("Scripting.FileSystemObject")
Set regEx = New RegExp

Set inFile = fso.OpenTextFile("c:\hoge\test1.htm")
Set outFile = fso.CreateTextFile("c:\hoge\test1_wk.htm")

◆動くケース:url_before = "test.asp\?param=999"
◆動かないケース:url_before = replace(rs.fields("item"), "?", "\?")
url_after = "test_999.htm"

regEx.pattern = url_before
repStr = url_after

Do Until inFile.AtEndOfStream
tempLine = inFile.ReadLine
repLine = regEx.Replace(tempLine, repStr)
outFile.WriteLine repLine
Loop

inFile.Close
outFile.Close

WSHを使い、あるhtmファイルの中にある特定の文字列を、RegEx.Replaceを使って置換しようとしています。通常の文字列置換についてはなんとか成功しているのですが、下記のケースで壁に当たっています。前に進める為にはどうしたらよいか、ヒントをご存知の方がいれば大変有り難く思います。

今回作業の特徴としては
1)置換前の文字列の中にメタキャラ「?」が含まれており、
2)置換前の文字列は、DBから読み込んできた文字列である
の2点です。(ちなみに1だけでは成功しているのですが、1と2が組み...続きを読む

Aベストアンサー

とりあえずテストコードを書いてみたけど、特に問題ないみたいです。
なのでやっぱり質問とか補足で書かれてないところで間違えてる可能性が高いかと。

コード:
Function iif(c,t,f)
If c Then
iif = t
Else
iif = f
End If
End Function

Set rs = WSCript.CreateObject( "ADODB.Recordset" )
rs.Open "T1", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb;"
url_before = Replace( rs.Fields( "item" ).Value, "?", "\?" )
url_after = rs.Fields( "replacer" ).Value
rs.Close

url_before_OK = "test.asp\?param=999"
WScript.Echo "1)", url_before, ":", iif( url_before = url_before_OK, "OK", "NG" )
Set re = new RegExp
re.Pattern = url_before

s1 = "/g/test.asp?param=999"
a1 = "/g/test_999.htm"
r1 = re.Replace( s1, url_after )
WScript.Echo "2)", s1, "->", r1, ":", iif( r1 = a1, "OK", "NG" )

データ db1.mdb テーブル T1の内容(左辺は列名):
item=test.asp?param=999, replacer=test_999.htm

実行結果:

1) test.asp\?param=999 : OK
2) /g/test.asp?param=999 -> /g/test_999.htm : OK

とりあえずテストコードを書いてみたけど、特に問題ないみたいです。
なのでやっぱり質問とか補足で書かれてないところで間違えてる可能性が高いかと。

コード:
Function iif(c,t,f)
If c Then
iif = t
Else
iif = f
End If
End Function

Set rs = WSCript.CreateObject( "ADODB.Recordset" )
rs.Open "T1", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb;"
url_before = Replace( rs.Fields( "item" ).Value, "?", "\?" )
url_after = rs.Fields( "replacer" ).Value
...続きを読む

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む


人気Q&Aランキング