ページ 1 / 1
C++ クラスのやりとりについて
Posted: 2016年7月17日(日) 20:27
by Toshita
いつもお世話になっております.
すごく初歩的なのですが、最近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++をあまり理解してなく,エラーを起こす理由がわからないです.
実体化とかなどの単語がでてきましたが,どういう理屈なのかわかりません.
勉強不足なのですが,どうぞ、よろしくおねがいします.
Re: C++ クラスのやりとりについて
Posted: 2016年7月17日(日) 20:41
by みけCAT
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;
}
具体的なエラーの内容と、実際に実験に使用したコード全体を提示していただけますか?
Re: C++ クラスのやりとりについて
Posted: 2016年7月17日(日) 21:45
by Toshita
ご返信有難うございます.
ソースの提示なのですが,かなり長いので下記のような対応を取らせて頂きました.
エラー内容はこちらです.
/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本体が必要になります.
長くなりましたが,よろしくお願い致します.
Re: C++ クラスのやりとりについて
Posted: 2016年7月17日(日) 22:08
by みけCAT
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などが足りず、コンパイルできませんでした。
Re: C++ クラスのやりとりについて
Posted: 2016年7月18日(月) 14:39
by Toshita
お返事遅れました.コンパイルできないことなのですが,
私のところでは勝手に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
長くなって来ましたが,
あと少しお付き合いお願います.
Re: C++ クラスのやりとりについて
Posted: 2016年7月18日(月) 17:48
by みけCAT
Toshita さんが書きました:コード:
CcdPhysicsDemo *ccdPhy = clientResetScene;
このような感じでなのでしょうか?
いいえ。
- エラーメッセージに書いてあるように、C++03ではクラスのメンバ変数の宣言にこのように初期化指定を書くことはできません。(C++11ならできます)
- エラーメッセージに書いてあるように、ここでもclientResetSceneは見える位置に宣言されていないので、使えません。
- clientResetSceneが定義されていないと指摘した呼び出し部分を修正しなければ、エラーが直せるわけないでしょう。(clientResetSceneを定義するという可能性も無くは無いですが、不適切でしょう)
Re: C++ クラスのやりとりについて
Posted: 2016年7月18日(月) 20:28
by Toshita
試行錯誤の末、このような形で解決いたしました.
大変お世話になりました.
コード:
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;
}
}