c++: Proper way to initialize static fields of member struct - c++

I got this:
// mouse.h
class Mouse {
private:
struct Pos {
static GLfloat x;
static GLfloat y;
};
static Pos last;
}
and this:
// mouse.cpp
// 1)
Mouse::Pos Mouse::last = {};
// 2)
Mouse::Pos Mouse::last = { 0.0, 0.0 };
// 3)
Mouse::last.x = 0.0f;
Mouse::last.y = 0.0f;
1), 2) and 3) are the attempts I've made at initializing that thing. I understand that the header should declare that last is static, and that the source should initialize it, but something has been wrong with all my attempts. Could someone please tell me the correct way to do such a thing? Am I missing some very important point? Is this nonsense? It is important that the fields are static. Thanks.

You don't need to declare Pos content as static.
// mouse.h
class Mouse {
private:
struct Pos {
GLfloat x;
GLfloat y;
};
static Pos last;
}
Mouse::Pos Mouse::last = { 0.0, 0.0 };
This should work too

It is important that the fields are static.
Then last will not have any state. It will simply refer to the static x and y values inside Mouse::Pos.
#include "mouse.h"
GLfloat Mouse::Pos::x = 10;
GLfloat Mouse::Pos::y = 10;
Mouse::Pos Mouse::last{};
wandbox example
The following asserts pass:
assert(Mouse::last.x == 10);
assert(Mouse::last.y == 10);

Related

VertexArray declaration inside a class

I'm trying to create a struct containing a point primitive and a method to draw it. However, declaration of a sf::VertexArray outside of method doesn't seem to work. The exactly same declaration inside a method works perfectly fine. Here are the code samples and the error. SFML version 2.1
edit: in both cases using namespace std; is used.
Works:
struct Point
{
int dot_x, dot_y;
sf::Color dot_color;
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green) {
dot_color = color;
dot_x = x;
dot_y = y;
}
virtual void draw() {
sf::VertexArray dot(sf::Points, 1);
dot[0].position = sf::Vector2f(dot_x,dot_y);
dot[0].color = dot_color;
window.draw(dot);
}
};
Does not work:
struct Point {
sf::VertexArray dot(sf::Points, 1);
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green) {
dot[0].position = sf::Vector2f(x,y);
dot[0].color = color;
}
virtual void draw() {
window.draw(dot);
}
};
Errors (all pointing at the VertexArray declaration string):
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: 'sf::Points' is not a type|
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: expected identifier before numeric constant|
E:\CodeBlocks\Labs\sem3\sfml1\main.cpp|64|error: expected ',' or '...' before numeric constant|
sf::VertexArray dot(sf::Points, 1);
This is a declaration of a variable with an initialiser: you can only write those at namespace or function scope. The parser is suitably confused, as you have it in your class scope. It's basically trying to parse it as a function declaration but, since neither sf::Points nor 1 are types, this approach ultimately fails also.
You should use the constructor's member initialiser list here:
struct Point
{
sf::VertexArray dot;
Point (int x = 50, int y = 50, sf::Color color = sf::Color::Green)
: dot(sf::Points, 1)
{
dot[0].position = sf::Vector2f(x,y);
dot[0].color = color;
}
virtual void draw()
{
window.draw(dot);
}
};

Passing an enum of a structure to other functions and assigning the values

I'm writing a Snake game in C++, I have a structure for a section of the snake which contains, data such as x position, y position, direction etc.
I have it all working, setting all the data to integers, I just would like to change some of the data types to enum's because it looks a lot neater and easier to understand.
I've tried lots and looked online but I can't seem to find anything.
This is some of the Structure:
struct SnakeSection
{
int snakePosX;
int snakePosY;
int SectionType;
// Tail = 0, Body = 1, Head = 2
int animation;
enum Direction
{
Up = 0,
Right = 1,
Down = 2,
Left = 3
};
};
My attempt at trying to pass one of the Directions to another function:
void PlayerSnake::createSnake()
{
// Parameters are direction, x and y pos, the blocks are 32x32
addSection(SnakeSection::Direction::Right, mStartX, mStartY, 2);
}
Then I tried setting the direction to the one passed in in that function:
void PlayerSnake::addSection(SnakeSection::Direction dir, int x, int y, int type)
{
//Create a temp variable of a Snake part structure
SnakeSection bufferSnake;
bufferSnake.Direction = dir;
bufferSnake.animation = 0;
//is it head tail or what? This is stored in the Snake section struct
//TODO Add different sprites for each section
bufferSnake.SectionType = type;
//assign the x and y position parameters to the snake section struct buffer
bufferSnake.snakePosX = x;
bufferSnake.snakePosY = y;
//Push the new section to the back of the snake.
lSnake.push_back(bufferSnake);
}
error: invalid use of enum SnakeSection::Direction
Thanks
The error on the following line ...
bufferSnake.Direction = dir;
... is reasoned, that besides declaring the enum type, you'll still have to have a class member variable to store it:
struct SnakeSection
{
int snakePosX;
int snakePosY;
int SectionType;
// Tail = 0, Body = 1, Head = 2
int animation;
enum Direction
{
Up = 0,
Right = 1,
Down = 2,
Left = 3
};
Direction direction_; // <<<<<<<<<<<<<< THAT'S WHAT'S MISSING IN YOUR CODE
};
And refer to
bufferSnake.direction_= dir; // <<<<<<<<<<<<<< THAT'S THE MEMBER VARIABLE YOU'LL
// HAVE TO REFER TO!

error C2146: syntax error : missing ';' before identifier 'ContextRecord'

i have a header file which contained all of the class' functions including code so the class didn't have a cpp file. everything worked. I added the cpp file and moved the function code over to that and now i get this error when compiling. the header that im getting the error in ((x86)\microsoft sdks\windows\v7.0a\include\winnt.h(6361)) isnt even included by the file that im changing. does anyone know what the reason for this might be? i can provide code i just don't know what would be helpful.
the cpp file:
#include "Fisherman.h"
void Fisherman::Initialise(){
memset((void*)&mListener, 0, sizeof(X3DAUDIO_LISTENER));
memset((void*)&mEmitter, 0, sizeof(X3DAUDIO_EMITTER));
memset((void*)&mDSPSettings, 0, sizeof(X3DAUDIO_DSP_SETTINGS));
XAUDIO2_VOICE_DETAILS details;
mCastSplash->GetSourceVoice()->GetVoiceDetails(&details);
mEmitter.ChannelCount = details.InputChannels;
mEmitter.CurveDistanceScaler = 1.0f;
X3DAUDIO_VECTOR emitterPos = { 0.0f, 0.0f, 0.0f};
mEmitter.Position = emitterPos;
X3DAUDIO_VECTOR emitterVel = { 0.0f, 0.0f, 0.0f };
mEmitter.Velocity = emitterVel;
mDSPSettings.SrcChannelCount = mEmitter.ChannelCount;
mDSPSettings.DstChannelCount = mXACore->GetChannelCount();
FLOAT32 * matrix = new FLOAT32[mDSPSettings.SrcChannelCount * mDSPSettings.DstChannelCount];
mDSPSettings.pMatrixCoefficients = matrix;
X3DAUDIO_VECTOR front = { 0.0f, 0.0f, 1.0f };
X3DAUDIO_VECTOR top = { 0.0f, 1.0f, 0.0f };
mListener.OrientFront = front;
mListener.OrientTop = top;
X3DAUDIO_VECTOR listenerVel = {0.0f, 0.0f, 0.0f};
mListener.Velocity = listenerVel;
X3DAUDIO_VECTOR listenerPos = { 0.0f, 0.0f, 0.0f };
mListener.Position = listenerPos;
}
void Fisherman::Rotate (int MouseDeltaX){
X3DAUDIO_VECTOR input = mListener.OrientFront;
X3DAUDIO_VECTOR result;
float theta = -(X3DAUDIO_PI/1000)*MouseDeltaX;
float cs = cos(theta);
float sn = sin(theta);
if(cs < 0.00001) cs = 0.0f;
result.x = input.x * cs - input.z * sn;
result.z = input.x * sn + input.z * cs;
result.y = 0.0f;
mListener.OrientFront = result;
}
bool Fisherman::Cast(Fish* aFish){
mCast->Play(0);
mCastOut = true;
mFish = aFish;
X3DAUDIO_VECTOR seg_v = Multiply(mListener.OrientFront, 30);
X3DAUDIO_VECTOR pt_v = {mFish->GetX(), 0.0f, mFish->GetZ()};
float proj_v_length = Dot(pt_v, mListener.OrientFront);
X3DAUDIO_VECTOR proj_v = Multiply(mListener.OrientFront, proj_v_length);
X3DAUDIO_VECTOR dist_v = Subtract(pt_v, proj_v);
if(VectorLength(dist_v) < mFish->GetRadius()){
mEmitter.Position = mFish->GetEmitter().Position;
return true;
}else{
mEmitter.Position = Multiply(mListener.OrientFront, 15);
return false;
}
}
void Fisherman::ReelIn(Fish* aFish){
mFish = aFish;
mFish->MoveCloser(mReelSpeed);
mReelingIn = true;
}
void Fisherman::ReelOut(Fish* aFish){
mFish = aFish;
mFish->MoveFurther();
mReelingIn = false;
}
void Fisherman::SetReelSpeed(float deltaTime){
float reelSpeed = 1.0f - deltaTime;
if(reelSpeed < 0.0f){
reelSpeed = 0.0f;
}
if(reelSpeed > 10){
mReelSpeedList.push_back(reelSpeed);
if(mReelSpeedList.size() > 3){
mReelSpeedList.pop_front();
}
reelSpeed = 0.0f;
std::list<float>::const_iterator iterator;
for (iterator = mReelSpeedList.begin(); iterator != mReelSpeedList.end(); ++iterator){
reelSpeed += *iterator;
}
mReelSpeed = reelSpeed/mReelSpeedList.size();
}else
mReelSpeed = reelSpeed;
mReelClickTimer = 0.1 / mReelSpeed;
}
void Fisherman::PlayReelClick(){
if(!mReelClick[0]->IsPlaying()){
mReelClick[0]->Play(0);
}else if(!mReelClick[1]->IsPlaying()){
mReelClick[1]->Play(0);
}else if(!mReelClick[2]->IsPlaying()){
mReelClick[2]->Play(0);
}else if(!mReelClick[3]->IsPlaying()){
mReelClick[3]->Play(0);
}else if(!mReelClick[4]->IsPlaying()){
mReelClick[4]->Play(0);
}else {
return;
}
}
bool Fisherman::NothingPlaying(){ // check to see if any sounds are playing
if(mCast->IsPlaying())return false;
if(mCastSplash->IsPlaying())return false;
for(int i =0; i < REEL_CLICK_OBJECTS; i++){
if(mReelClick[i]->IsPlaying()){
return false;
}
}
return true;
}
void Fisherman::SetReelingIn(bool isReelingIn){
mReelingIn = isReelingIn;
}
void Fisherman::SetCastOut(bool hasCastOut){
mCastOut = hasCastOut;
}
float Fisherman::GetReelClickTime(){
return mReelClickTimer/CLICK_TIMER_MULTIPLIER;
}
bool Fisherman::IsReelingIn(){
return mReelingIn;
}
float Fisherman::GetReelSpeed(){
return mReelSpeed;
}
X3DAUDIO_LISTENER Fisherman::GetListener(){
return mListener;
}
X3DAUDIO_EMITTER Fisherman::GetEmitter(){
return mEmitter;
}
X3DAUDIO_DSP_SETTINGS Fisherman::GetSettings(){
return mDSPSettings;
}
XASound* Fisherman::GetCastSound(){
return mCast;
}
XASound* Fisherman::GetCastSplashSound(){
return mCastSplash;
}
bool Fisherman::HasCastSplashed(){
return mCastSplashBool;
}
void Fisherman::SetCastSplashed(bool splashed){
mCastSplashBool = splashed;
}
bool Fisherman::IsCastOut(){
return mCastOut;
}
the header:
#ifndef _FISHERMAN_H_
#define _FISHERMAN_H_
#include <X3DAudio.h>
#include <math.h>
#include <list>
#include "VectorCalculations.h"
#include "Fish.h"
#include "XASound.hpp"
using AllanMilne::Audio::XASound;
const float CLICK_TIMER_MULTIPLIER = 2.5f;
const int REEL_CLICK_OBJECTS = 5;
class Fisherman{
public:
Fisherman(XACore* aXACore, XASound *cast, XASound *castSplash, std::list<XASound*> reelClickList)
: // a Fish Object pointer for the fisherman to interact with.
mFish (NULL), mXACore (aXACore),
//XASound objects with sounds for the fisherman
mCast (cast), mCastSplash (castSplash)
{
mReelSpeedList.clear();
for(int i = 0; i < REEL_CLICK_OBJECTS; i++){
mReelClick[i] = reelClickList.front();
mReelClick[i]->SetVolume(2.0f);
reelClickList.pop_front();
mReelClickList.push_back(mReelClick[i]);
}
mCastSplash->SetVolume(7.0f);
mXACore = aXACore;
mCastSplashBool = false;
mCastOut = false;
mReelingIn = false;
mCastDistance = 0.0f;
Initialise();
}
~Fisherman(){}
void Initialise();
void Rotate(int MouseDeltaX);
bool Cast(Fish* aFish);
void ReelIn(Fish* aFish);
void ReelOut(Fish* aFish);
void SetReelSpeed(float deltaTime);
void PlayReelClick();
bool NothingPlaying(); // check to see if any sounds are playing
void SetFront(X3DAUDIO_VECTOR front);
void SetReelingIn(bool isReelingIn);
void SetCastOut(bool hasCastOut);
float GetReelClickTime();
bool IsReelingIn();
float GetReelSpeed();
X3DAUDIO_LISTENER GetListener();
X3DAUDIO_EMITTER GetEmitter();
X3DAUDIO_DSP_SETTINGS GetSettings();
XASound* GetCastSound();
XASound* GetCastSplashSound();
bool HasCastSplashed();
void SetCastSplashed(bool splashed);
bool IsCastOut();
private:
XACore *mXACore;
XASound *mCast;
XASound *mCastSplash;
XASound *mReelClick[REEL_CLICK_OBJECTS];
float mCastDistance;
float mReelClickTimer;
float mReelSpeed;
std::list<float> mReelSpeedList;
std::list<XASound*> mReelClickList;
X3DAUDIO_LISTENER mListener;
X3DAUDIO_EMITTER mEmitter;
X3DAUDIO_DSP_SETTINGS mDSPSettings;
Fish *mFish;
bool mCastOut;
bool mCastSplashBool;
bool mReelingIn;
};
#endif
including windows.h at the top of the header file solved this issue.
Does the error also say PCONTEXT undefined?
Try adding #include <Windows.h> before #include <X3DAudio.h>.
In reply to comment about unresolved external symbol:
That's because you didn't define Fisherman::SetFront in the cpp file.
Whole code would be helpfull. Did you remember obvious to give namespace to names of functions etc?
class A { void foo() { } };
=>
class A { void foo(); }
void A::foo() { ... }
etc?
Fastest way would be reverting back to state when it worked, and not moving whole at once, but only one function at a time. Then when problem would occure you could give us that specific code or try to fix it yourself.
It is very possible that there is just a missed ';', somewhere before this line.
Double-check your code, remember that everything you define in a cpp file has to already be declared in your class definition.
I'd prefer to post a comment, but apparently I'm not allowed.
Anyway, as a simpler way to give us a feel of what you're trying to do, definatley post your code - it does not have to be exactly as you use, but should be a concise piece of generic code, highlighting how you are doing something. (SSCCE) If it really is a bug in how you typed it, it would be good to have your exact code, but put it on pastebin and provide a link so that this page doesn't end up with reams of code.
EDIT:
winnt.h apparently causes all sorts of problems: Weird compile error dealing with Winnt.h
it is used to provide definitions for winAPI specific headers, as far as I know. One of the solutions proposed on that thread is to get the definitions from a different windows header before including whichever header requires those definitions.

Struct property that returns a struct of its own type

I'm trying to define a struct in C++ that has properties to return pre-defined values of it's own type.
Like many APIs have for Vectors and Colors like:
Vector.Zero; // Returns a vector with values 0, 0, 0
Color.White; // Returns a Color with values 1, 1, 1, 1 (on scale from 0 to 1)
Vector.Up; // Returns a vector with values 0, 1 , 0 (Y up)
Source: http://msdn.microsoft.com/en-us/library/system.drawing.color.aspx
(MSDN's page of their Color type)
I've been trying to search for hours but I can't for the heart of me even figure out what it's called.
//in h file
struct Vector {
int x,y,z;
static const Vector Zero;
};
// in cpp file
const Vector Vector::Zero = {0,0,0};
Like this?
You can mimic it with static members:
struct Color {
float r, g, b;
Foo(float v_r, float v_g, float v_b):
r(v_r), g(v_g), b(v_b){};
static const Color White;
};
const Color Color::White(1.0f, 1.0f, 1.0f);
// In your own code
Color theColor = Color::White;
This is a static property. Unfortunately, C++ does not have properties of any type. To implement this, you probably want either a static method or a static variable. I would recommend the former.
For the Vector example, you would want something like:
struct Vector {
int _x;
int _y;
int _z;
Vector(int x, int y, int z) {
_x = x;
_y = y;
_z = z;
}
static Vector Zero() {
return Vector(0,0,0);
}
}
You would then write Vector::Zero() to get the zero vector.

non static or const array syntax

what's wrong with this syntax? sorry for the newbie question.
source:
Level::Level()
{
NintyDegreeDirections[4] =
{
1.0f, 1.4f, 2.4f, 0.1f
}
...rest of class
header:
//all necessary includes
class Level
{
private:
float NintyDegreeDirections[4];
...rest of header
how do I have an array as a instance member? I'm converting from C#
In the current version of C++ (C++11), you can initialize the member array like this:
Level::Level()
: NintyDegreeDirections( { 1.0f, 1.4f, 2.4f, 0.1f } )
{
}
C++11 isn't universally supported and if you don't have support for this in your compiler you will have to assign to each member in turn.
E.g.:
NintyDegreeDirections[0] = 1.0f;
NintyDegreeDirections[1] = 1.4f;
//...
Did you try:
NintyDegreeDirections[0] = 1.0f;
NintyDegreeDirections[1] = 1.4f;
/* ... */