C++ クラスのやりとりについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Toshita
記事: 23
登録日時: 9年前

C++ クラスのやりとりについて

#1

投稿記事 by Toshita » 9年前

いつもお世話になっております.
すごく初歩的なのですが、最近C++をはじめまして、クラス外のものを呼び出したいのです.
下記のような2つのクラスがあったとします.

1つめ

コード:

class SampleListener : public Listener {
  	public:
    		virtual void onInit(const Controller&);
    		virtual void onConnect(const Controller&);
    		virtual void onDisconnect(const Controller&);
    		virtual void onExit(const Controller&);
    		virtual void onFrame(const Controller&);
    		virtual void onFocusGained(const Controller&);
    		virtual void onFocusLost(const Controller&);
	private:
		CcdPhysicsDemo *ccdPhy;	
};
2つめ

コード:

class CcdPhysicsDemo : public PlatformDemoApplication,Listener
{
		
	//deletion/cleanup時のために衝突形を保持
	btAlignedObjectArray<btCollisionShape*>	m_collisionShapes;
public:
	
	CcdPhysicsDemo();
	
	void    leap_flag();
	virtual ~CcdPhysicsDemo()
	{
		exitPhysics();
	}
	void	initPhysics();
	void	exitPhysics();

	virtual void clientMoveAndDisplay();

	void displayText();

	virtual void keyboardCallback(unsigned char key, int x, int y);

	virtual void 	displayCallback();
	virtual void	shootBox(const btVector3& destination);
	virtual void	clientResetScene();
このような宣言をした後に,

void SampleListener::onFrame(const Controller& controller)
から
void CcdPhysicsDemo::clientResetScene()

を呼び出したいのですが,c++をあまり理解してなく,エラーを起こす理由がわからないです.

実体化とかなどの単語がでてきましたが,どういう理屈なのかわかりません.
勉強不足なのですが,どうぞ、よろしくおねがいします.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++ クラスのやりとりについて

#2

投稿記事 by みけCAT » 9年前

Toshita さんが書きました:エラーを起こす理由がわからないです.
適当に補完した所、コンパイルを通すことができました。

コード:

#include <iostream>

typedef int Controller;
class CcdPhysicsDemo;
class Listener {};
class PlatformDemoApplication {};
template<typename T> class btAlignedObjectArray {};
typedef int btCollisionShape;
typedef int btVector3;

class SampleListener : public Listener {
    public:
            virtual void onInit(const Controller&);
            virtual void onConnect(const Controller&);
            virtual void onDisconnect(const Controller&);
            virtual void onExit(const Controller&);
            virtual void onFrame(const Controller&);
            virtual void onFocusGained(const Controller&);
            virtual void onFocusLost(const Controller&);
    private:
        CcdPhysicsDemo *ccdPhy; 
};

class CcdPhysicsDemo : public PlatformDemoApplication,Listener
{
        
    //deletion/cleanup時のために衝突形を保持
    btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
public:
    
    CcdPhysicsDemo();
    
    void    leap_flag();
    virtual ~CcdPhysicsDemo()
    {
        exitPhysics();
    }
    void    initPhysics();
    void    exitPhysics();
 
    virtual void clientMoveAndDisplay();
 
    void displayText();
 
    virtual void keyboardCallback(unsigned char key, int x, int y);
 
    virtual void    displayCallback();
    virtual void    shootBox(const btVector3& destination);
    virtual void    clientResetScene();
};

void SampleListener::onFrame(const Controller& controller) {
    CcdPhysicsDemo cpd;
    cpd.clientResetScene();
}

void CcdPhysicsDemo::clientResetScene() {
    std::cout << "hello, world\n";
}

void SampleListener::onInit(const Controller&) {}
void SampleListener::onConnect(const Controller&) {}
void SampleListener::onDisconnect(const Controller&) {}
void SampleListener::onExit(const Controller&) {}
void SampleListener::onFocusGained(const Controller&) {}
void SampleListener::onFocusLost(const Controller&) {}

CcdPhysicsDemo::CcdPhysicsDemo() {}
void CcdPhysicsDemo::exitPhysics() {}
void CcdPhysicsDemo::clientMoveAndDisplay() {}
void CcdPhysicsDemo::keyboardCallback(unsigned char key, int x, int y) {}
void CcdPhysicsDemo::displayCallback() {}
void CcdPhysicsDemo::shootBox(const btVector3& destination) {}

int main() {
    SampleListener sl;
    Controller c;
    sl.onFrame(c);
    return 0;
}
具体的なエラーの内容と、実際に実験に使用したコード全体を提示していただけますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Toshita
記事: 23
登録日時: 9年前

Re: C++ クラスのやりとりについて

#3

投稿記事 by Toshita » 9年前

ご返信有難うございます.
ソースの提示なのですが,かなり長いので下記のような対応を取らせて頂きました.
エラー内容はこちらです.
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp: メンバ関数 ‘virtual void SampleListener::onFrame(const Leap::Controller&)’ 内:
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp:69:17: 警告: 変数 ‘currentPosition’ が設定されましたが使用されていません [-Wunused-but-set-variable]
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp:61:14: 警告: 変数 ‘handCenter’ が設定されましたが使用されていません [-Wunused-but-set-variable]
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp:93:21: エラー: ‘clientResetScene’ was not declared in this scope
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/src/LinearMath/btScalar.h: 大域スコープ:
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/src/LinearMath/btScalar.h:337:14: 警告: ‘btInfinityMask’ が定義されましたが使用されません [-Wunused-variable]
make[2]: *** [Demos/CcdPhysicsDemo/CMakeFiles/AppCcdPhysicsDemo.dir/CcdPhysicsDemo.o] エラー 1
make[1]: *** [Demos/CcdPhysicsDemo/CMakeFiles/AppCcdPhysicsDemo.dir/all] エラー 2
make: *** [all] エラー 2
私はこのプログラムをつくった環境は
Linux です.
Bullet, LeapMotion, OpenGL, Glut, C++, CMake を用いています.

Bulletについてるデモで勉強してたので,ソースや必要なファイルが多いので,下記のGithubに上げて見ました.

https://github.com/minhyeong/Leap-Study

ソースファイルは以下の3つです.
main.cpp
CcdPhysicsDemo.cpp
CcdPhysicsDemo.h

一応このファイル単体でコンパイルできますが,CMakeを行うと,Makefileが不必要に書き換えられて,コンパイルできなくなるし,Bullet本体が必要になります.

長くなりましたが,よろしくお願い致します.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++ クラスのやりとりについて

#4

投稿記事 by みけCAT » 9年前

Toshita さんが書きました:/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp:93:21: エラー: ‘clientResetScene’ was not declared in this scope
clientResetSceneはグローバルにもSampleListenerにもListenerにも宣言されていないので、当然ここでは使えません。
ここで使用したいclientResetSceneはCcdPhysicsDemoクラスの静的でないメンバ関数なので、
CcdPhysicsDemoクラスのインスタンスを用意(例えばccdPlyメンバに代入?)し、そのインスタンスに対して呼び出す必要があります。
Toshita さんが書きました:ソースファイルは以下の3つです.
main.cpp
CcdPhysicsDemo.cpp
CcdPhysicsDemo.h

一応このファイル単体でコンパイルできますが
DemoApplication.hやLinearMath/btAlignedObjectArray.hなどが足りず、コンパイルできませんでした。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Toshita
記事: 23
登録日時: 9年前

Re: C++ クラスのやりとりについて

#5

投稿記事 by Toshita » 9年前

お返事遅れました.コンパイルできないことなのですが,
私のところでは勝手にBulletから参照してくれてただけみたいでした.
申し訳ありません.多分、Githubに上げなおしたtar.gzで,コンパイルできると思います.
https://github.com/minhyeong/Leap-Study
みけCAT さんが書きました: clientResetSceneはグローバルにもSampleListenerにもListenerにも宣言されていないので、当然ここでは使えません。
ここで使用したいclientResetSceneはCcdPhysicsDemoクラスの静的でないメンバ関数なので、
CcdPhysicsDemoクラスのインスタンスを用意(例えばccdPlyメンバに代入?)し、そのインスタンスに対して呼び出す必要があります。
とのご指摘なのですが,

コード:

CcdPhysicsDemo *ccdPhy = clientResetScene;
このような感じでなのでしょうか?

下記のように直したのですが,エラーがきえず,
あまり理解できてないようで...
In file included from /usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/main.cpp:3:0:
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h:92:28: エラー: ‘clientResetScene’ was not declared in this scope
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h:92:28: エラー: ISO C++ forbids initialization of member ‘ccdPhy’ [-fpermissive]
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h:92:28: エラー: making ‘ccdPhy’ static [-fpermissive]
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/Demos/CcdPhysicsDemo/CcdPhysicsDemo.h:92:28: エラー: invalid in-class initialization of static data member of non-integral type ‘CcdPhysicsDemo*’
/usrhome/IS15/c501506046/bullet-2.4.82-r2704/src/LinearMath/btScalar.h:337:14: 警告: ‘btInfinityMask’ が定義されましたが使用されません [-Wunused-variable]
make[2]: *** [Demos/CcdPhysicsDemo/CMakeFiles/AppCcdPhysicsDemo.dir/main.o] エラー 1
make[1]: *** [Demos/CcdPhysicsDemo/CMakeFiles/AppCcdPhysicsDemo.dir/all] エラー 2
make: *** [all] エラー 2

コード:

#ifndef BT_CCD_PHYSICS_DEMO_H
#define BT_CCD_PHYSICS_DEMO_H

#ifdef _WINDOWS
#include "Win32DemoApplication.h"
#define PlatformDemoApplication Win32DemoApplication
#else
#include "GlutDemoApplication.h"
#define PlatformDemoApplication GlutDemoApplication
#endif

#include "LinearMath/btAlignedObjectArray.h"
#include "Leap.h"
#include <stdio.h>

using namespace Leap;
class CcdPhysicsDemo;

class btBroadphaseInterface;
class btCollisionShape;
class btOverlappingPairCache;
class btCollisionDispatcher;
class btConstraintSolver;
struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;

class CcdPhysicsDemo : public PlatformDemoApplication,Listener
{
		
	//deletion/cleanup時のために衝突形を保持
	btAlignedObjectArray<btCollisionShape*>	m_collisionShapes;
	
	btBroadphaseInterface*	m_broadphase;

	btCollisionDispatcher*	m_dispatcher;

	btConstraintSolver*	m_solver;

	enum
	{
		USE_CCD=1,
		USE_NO_CCD
	};
	int 	m_ccdMode;

	btDefaultCollisionConfiguration* m_collisionConfiguration;

	public:
	
	CcdPhysicsDemo();
	
	void    leap_flag();
	virtual ~CcdPhysicsDemo()
	{
		exitPhysics();
	}
	void	initPhysics();
	void	exitPhysics();

	virtual void clientMoveAndDisplay();

	void displayText();

	virtual void keyboardCallback(unsigned char key, int x, int y);
	virtual void 	displayCallback();
	virtual void	shootBox(const btVector3& destination);
	virtual void	clientResetScene();

	
	static DemoApplication* Create()
	{
		CcdPhysicsDemo* demo = new CcdPhysicsDemo;
		demo->myinit();
		demo->initPhysics();
		return demo;
	}

	
};

class SampleListener : public Listener {
  	public:
    		virtual void onInit(const Controller&);
    		virtual void onConnect(const Controller&);
    		virtual void onDisconnect(const Controller&);
    		virtual void onExit(const Controller&);
    		virtual void onFrame(const Controller&);
    		virtual void onFocusGained(const Controller&);
    		virtual void onFocusLost(const Controller&);
	private:
		CcdPhysicsDemo *ccdPhy = clientResetScene;
		
};

#endif //BT_CCD_PHYSICS_DEMO_H

長くなって来ましたが,
あと少しお付き合いお願います.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: C++ クラスのやりとりについて

#6

投稿記事 by みけCAT » 9年前

Toshita さんが書きました:

コード:

CcdPhysicsDemo *ccdPhy = clientResetScene;
このような感じでなのでしょうか?
いいえ。
  • エラーメッセージに書いてあるように、C++03ではクラスのメンバ変数の宣言にこのように初期化指定を書くことはできません。(C++11ならできます)
  • エラーメッセージに書いてあるように、ここでもclientResetSceneは見える位置に宣言されていないので、使えません。
  • clientResetSceneが定義されていないと指摘した呼び出し部分を修正しなければ、エラーが直せるわけないでしょう。(clientResetSceneを定義するという可能性も無くは無いですが、不適切でしょう)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Toshita
記事: 23
登録日時: 9年前

Re: C++ クラスのやりとりについて

#7

投稿記事 by Toshita » 9年前

試行錯誤の末、このような形で解決いたしました.
大変お世話になりました.

コード:

class CcdPhysicsDemo : public PlatformDemoApplication,Listener
{
		
	//deletion/cleanup時のために衝突形を保持
	btAlignedObjectArray<btCollisionShape*>	m_collisionShapes;
	
	btBroadphaseInterface*	m_broadphase;

	btCollisionDispatcher*	m_dispatcher;

	btConstraintSolver*	m_solver;

	enum
	{
		USE_CCD=1,
		USE_NO_CCD
	};
	int 	m_ccdMode;

	btDefaultCollisionConfiguration* m_collisionConfiguration;

	public:
	
	CcdPhysicsDemo();
	
	void    leap_flag();
	virtual ~CcdPhysicsDemo()
	{
		exitPhysics();
	}
	void	initPhysics();
	void	exitPhysics();

	virtual void clientMoveAndDisplay();

	void displayText();

	virtual void keyboardCallback(unsigned char key, int x, int y);
	virtual void 	displayCallback();
	virtual void	shootBox(const btVector3& destination);
	void	clientResetScene();

	
	static DemoApplication* Create()
	{
		CcdPhysicsDemo* demo = new CcdPhysicsDemo;
		demo->myinit();
		demo->initPhysics();
		return demo;
	}

	
};

class SampleListener : public Listener {
  	public:
		SampleListener(CcdPhysicsDemo *ccph);
    		virtual void onInit(const Controller&);
    		virtual void onConnect(const Controller&);
    		virtual void onDisconnect(const Controller&);
    		virtual void onExit(const Controller&);
    		virtual void onFrame(const Controller&);
    		virtual void onFocusGained(const Controller&);
    		virtual void onFocusLost(const Controller&);
		void leap();
	private:
		CcdPhysicsDemo *ccdPhy;
};

コード:

//ジェスチャーの処理
  	GestureList gestures = frame.gestures();
  	for (i = 0; i < gestures.count(); i++){
    		Gesture gesture = gestures[i];

    		//ジェスチャーの種類の出力
    		printf("  gesture[%d] ",i);
    		switch (gesture.type()) {
      		case Gesture::TYPE_CIRCLE:
        		printf("CIRCLE\n");
        		break;
      		case Gesture::TYPE_SWIPE:
        		printf("SWIPE\n");
        		break;
      		case Gesture::TYPE_KEY_TAP:
        		printf("KEY_TAP\n");
			//ccdPhy->clientResetScene();
			ccdPhy->initPhysics();//core
        		break;
      		case Gesture::TYPE_SCREEN_TAP:
        		printf("SCREEN_TAP\n");
        		break;
      		default:
        		printf("unknown\n");
        		break;
    		}
  	}

閉鎖

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