clsB::vfFuncB関数ないで
clsA::lVarAにアクセスする方法がありましたら
教えて下さい。

#include <stdio.h>

class clsB{
public:
clsB(){};
~clsB(){};
void vfFuncB(){
printf("clsB::vfFuncB\n");
printf("clsA::lVarAをアクセスしたい\n");
};
};

class clsA{
public:
clsA(){};
~clsA(){};
void vfFuncA(void){
clsB oB;
oB.vfFuncB();
};
void vfSet(long lA){lVarA=lA;}
long lfGet(void) {return lVarA;}
private:
long lVarA;
};

void main(void)
{
clsA oA;
oA.vfFuncA();
}

このQ&Aに関連する最新のQ&A

A 回答 (5件)

>ゆえにclsAのコンストラクタを細工するのは避けたい。


clsBのコンストラクタですよね?

>また、clsBがclsAの寿命中に常に常駐するのは避けたい。
vfFuncA()のメソッド中に clsBを宣言しているので、vfFuncAの実行時に clsBはスタックに実体がとられ、vfFuncA終了と共に解放されるので常にメモリをとられているわけではありません。

>がてるのです。何処が悪いの?
clsBの構造を先に定義しないとだめなんじゃないでしょうか。
また、以下のコードは、
 void vfFuncB(clsA* oB){
  oB.vfSet(123);
 };
ポインタで渡されているから、oB->vfSet(123); ですね。
    • good
    • 0

他の方と似たような回答になりますが、clsA と clsB の関係が、vfFuncA() を


呼ぶ間だけの、「疎」な関係に有るのであれば、clsA.vfFuncA() で、clsB.vfFuncB() を
呼ぶときに、自分( clsA のオブジェクト)を渡すようにする方が良いでしょう。

class clsB {
 …
 void vfFuncB(clsA* a); /* メソッドの定義は後で */
{
  printf("clsA::lVarA is %ld\n", a.lfGet());
 }
};

class clsA {
 …
 void vfFuncA(void) {
  clsB oB;
  oB.vfFuncB(this);
 }
};

void clsB::vfFuncB(clsA* a)
{
 printf("clsA::lVarA is %ld\n", a.lfGet());
}

clsA と clsB の関係が「密」であるならば、yatokesa さんの回答にあるように
コンストラクタで関連を持たせるようにする方が良いです。
    • good
    • 0
この回答へのお礼

class A {
public:
void f(){B b; b.f(this)};
void set(long x){v=x;}
private:
long v;
};

class B {
public:
void f(A* a) {
a->set(123);
}
};

void main() {
A a;
a.f();
}
で実装しました。

お礼日時:2001/09/18 17:01

vf が virtual function のような気がしたので、私は継承について少し。



class clsA {
protected:
 long lVarA;
public:
 virtual void vfFunc() {
  「clsAの処理」;
 }
};

class clsB : public clsA { // clsBはclsAの機能を拡張する
public:
 void vfFunc() {
  clsA::vfFunc(); // まず、clsAとしての処理を行う
  「clsBの追加処理、lVarAもアクセスできる」;
 }
};

void main()
{
 clsA oA; clsB oB;
 oA.vFunc();
 oB.vFunc();
}
    • good
    • 0

私もあまり詳しくはないのですが、確か出来なかったと思います。

ので、わたしは clsBを生成するときに clsAを渡し、clsBのコンストラクタの中でメンバー変数に保存するようにしています。

class clsB{
public:
 clsB(clsA* pA){m_pA = pA};
 ~clsB(){};
 void vfFuncB(){
  printf("clsB::vfFuncB\n");
  printf("clsA::lVarAをアクセスしたい\n");
 };
private:
 m_pA;
};

クラス生成時
clsB oB(this);

ってな具合ですが、どうでしょう?
    • good
    • 0

こんにちわ



以前にも似たような質問があり、僕も回答させてもらいましたので、
それを紹介しておきます。

頑張ってください!

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=109273

この回答への補足

実際にはclsAはATLのCOMのメソッドです。
ゆえにclsAのコンストラクタを細工するのは避けたい。
また、clsBがclsAの寿命中に常に常駐するのは避けたい。

ところで
(10) : error C2079: 'oB' が 未定義の class 'clsB' で使用されています。
(11) : error C2228: '.vfFuncB' : 左側がクラス、構造体、共用体ではありません。
がてるのです。何処が悪いの?

#include <stdio.h>

class clsB;
class clsA{
friend class clsB;
public:
 clsA(){};
 ~clsA(){};
 void vfFuncA(){
  clsB oB;
  oB.vfFuncB(this);
 }
 void vfSet(long lA){lVarA=lA;}
 long lfGet(void) {return lVarA;}
private:
 long lVarA;
};

class clsB{
public:
 clsB(){};
 ~clsB(){};
 void vfFuncB(clsA* oB){
  oB.vfSet(123);
 };
};

// COMの呼び出し側はclsBの存在を知らない。
void main(void)
{
 clsA oA;
 oA.vfFuncA();
}

補足日時:2001/09/18 15:11
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人が検索しているワード

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

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;
}

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オブジェクトのデストラクタが呼び出される。

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

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Qint main()、void main()、void main(void)、int main(void)

今日、大学でC言語の講義の時間、先生が、

#include <stdio.h>

void main(void){

}

と宣言してプログラムを書くと教えていました。
main関数には、
main()
void main()
void main( void )
int main()
int main( void )

と、人によりいくつかの描き方があったりします。
どれが本当は正しいのでしょうか?
void mainはすべきではないとなんかの本で読んだのですが・・。

Aベストアンサー

通称C89という以前の言語規格(現行コンパイラの多くが準拠)では、下記のいずれかが正しい。
int main(int argc, char *argv[])
int main(void)

但し、最新のC言語規格(通称C99)では、
<ISO/IEC9899:1999>
or in some other implementation-defined manner.
</ISO/IEC9899:1999>
となっているので、処理系が戻り値のvoidを認めていればvoidも可。
# 組込み系などで戻り値を使わない環境もあるためでしょうか。

なので、コンパイラのマニュアルで戻り値のvoidにしていい/しろと書いてない限り、
voidは言語仕様的には正しくない。(でも動くものもある)

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ランキング

おすすめ情報