Error C2659 in C++ Visual Studio - c++

I am new to this and to programming in C++
I keep getting the error Errors: 1 error C2659: '=' : function as left operand W:\CGT 215\Final Project\game\game\paddle.cpp 11 1 game
2 IntelliSense: expression must be a modifiable lvalue w:\CGT 215\Final Project\game\game\paddle.cpp 11 2 game
#include "Paddle.h"
#include <iostream>
Paddle::Paddle(int width, int height, float (*Controller)())
{
m_position.x = 100;
m_position.y = 100;
m_width = width;
m_height = height;
Control = Controller;
}
void Paddle::Update()
{
m_position.y += *Control();
}

Given the error code, as documented here, Control seems to be an existing function and not a function pointer hence cannot be assigned. You want to define another field to hold the function pointer.
Here a code sample to do that:
struct Paddle
{
float (*Control)();
...
Paddle(int width, int height, float (*Controller)());
void Update();
};
Then, your Update implementation should not dereference the Control function pointer:
void Paddle::Update()
{
m_position.y += Control();
}
Your update function may remain unchanged.

Related

error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject' when I calling hDC.SelectObject function in MFC

I develop a simple program in MFC (Visual Studio 2013) for WinCE 2013, using GDI methods for drawing on device context.
Unfortunatelly when I try to call SelectObject on context device handle i get error:
"error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject"
I attach one of functions which calls SelectObject method.
BOOL Druk::DrawGrid(CDC hDC,int start_x, int start_y, int limit_x, int limit_y, int width)
{
CPen pen;
COLORREF linecol;
pen.CreatePen(PS_SOLID, width, NULL);
hDC.SelectObject(&pen);
for (float i = start_y; i < limit_y; i += 5 * MILIMETER)
{
hDC.MoveTo(start_x, i);
hDC.LineTo(limit_x, i);
}
for (float j = start_x; j < limit_x; j += 5 * MILIMETER)
{
hDC.MoveTo(j, start_y);
hDC.LineTo(j, limit_y);
}
for (float i = start_x; i < limit_x; i += MILIMETER)
{
for (float j = start_y; j < limit_y; j += MILIMETER)
{
hDC.MoveTo(i, j);
hDC.LineTo(i + 1, j);
}
}
return TRUE;
}
I try to google this error but I cannot find sth what can help me.
Your code for SelectObject() looks fine to me. HOWEVER, passing a CDC by value is a big error. You should pass it by reference or pass a pointer to a CDC. I would expect to maybe see an error for when the argument CDC hDC tries to make a copy. The copy constructor and assignment operator for CObject are declared private and unimplemented. You cannot make a copy of them. Instead, change the signature of your function to:
BOOL Druk::DrawGrid(CDC& hDC,int start_x, int start_y, int limit_x, int limit_y, int width)
{
// your code
}
You also have some other problems... you need to save the originally selected pen and then select it back into the CDC at the end....
CPen* pOldPen = hdc.SelectObject(&pen);
at the end
hdc.SelectObject(pOldPen);

Why is my class variable changing its value between methods?

I am trying to load a bitmap animation to the screen. I have a float variable holdTime that is specified to hold the "holdtime" value for the animation. In my constructor I set the holdtimevariable to 0.1f but when I try to access the method in the class that is using the holdTime variable, the value of holdTime has changed to -107374176f. So somewhere between my constructor call and the method call the value has changed from 0.1f to -107374176f.
To make things a little bit more clearer let me show you some code:
Here is the header file for the Game class, this is where I call the constructor of the Animation class that has the holdTime variable.
#pragma once
#include "Graphics.h"
#include "Surface.h"
#include "Animation.h"
#include "FrameTimer.h"
class Game
{
public:
Game( class MainWindow& wnd );
void Go();
private:
void UpdateModel();
private:
MainWindow& wnd;
FrameTimer ft;
Surface surf = Surface("Test32x48.bmp");
Animation testAnimation = Animation(0, 0, 32, 48, 4, surf, 0.1f);
};
You see that I have this testAnimation at the bottom of the class. The last argument in the constructor call is the value that is ought be in holdTime.
This is how my Animation header file looks like:
#include "Surface.h"
#include "Graphics.h"
#include <vector>
class Animation {
public:
Animation(int x, int y, int width, int height, int count, const Surface& sprite, float holdtime, Color chroma = Colors::Magenta);
void Update(float dt);
private:
void Advance();
private:
std::vector<RectI> frames;
int iCurFrame = 0;
float holdTime = 0;
float curFrameTime = 0.0f;
};
And this is the Animation Cpp file:
#include "Animation.h"
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
void Animation::Update(float dt)
{
curFrameTime += dt;
while(curFrameTime >= holdTime) {
Advance();
curFrameTime -= holdTime;
}
}
void Animation::Advance()
{
if (++iCurFrame >= frames.size()) {
iCurFrame = 0;
}
}
There is only one method that is making use of holdTime and that is the method Update(float dt).
If we go back to the Game class and look at the Game.cpp file:
#include "MainWindow.h"
#include "Game.h"
Game::Game( MainWindow& wnd )
:
wnd( wnd ),
gfx( wnd )
{
}
void Game::Go()
{
UpdateModel();
}
void Game::UpdateModel()
{
testAnimation.Update(ft.Mark());
}
In the Method Go() we call the method UpdateModel() which in turn is calling the Update() method in the animation class. This means that the first method to be executed in the Animation class after the constructor call is the update() method. When I debug the program I can see that the value of holdtime has changed between the constructor call and the Update() method call. But I don't know how since it I am not modifying the value somewhere else. It also seemes that the new value of holdTime is garbage value.
It became a lot of code in this question and it looks a bit messy and even though I lack the skills of writing a good Title I hope I made you somewhat clear what my problem is.
Thanks!
Update:
Here is the code for the FrameTimer class since the value returned from one of its methods is passed in into the Update() method:
FrameTimer.H:
#pragma once
#include <chrono>
class FrameTimer
{
public:
FrameTimer();
float Mark();
private:
std::chrono::steady_clock::time_point last;
};
FrameTimer.cpp:
#include "FrameTimer.h"
using namespace std::chrono;
FrameTimer::FrameTimer()
{
last = steady_clock::now();
}
float FrameTimer::Mark()
{
const auto old = last;
last = steady_clock::now();
const duration<float> frameTime = last - old;
return frameTime.count();
}
Edit:
main.cpp:
int WINAPI wWinMain( HINSTANCE hInst,HINSTANCE,LPWSTR pArgs,INT )
{
MainWindow wnd( hInst,pArgs );
Game game( wnd );
while( wnd.ProcessMessage() )
{
game.Go();
}
}
As you can see the game.Go() method is the first method that is called in main.
Your Animation constructor is at fault:
Animation::Animation(int x, int y, int width, int height, int count,
const Surface& sprite, float holdtime, Color chroma)
:
sprite(sprite),
holdTime(holdTime),
chroma(chroma)
{
for (int i = 0; i < count; i++)
{
frames.emplace_back(x + i * width, x + (i + 1) * width,y, y + height);
}
}
Here you attempt to initialise the member holdTime from the parameter holdTime.
Except, there is no parameter holdTime. There is only the parameter holdtime.
Hence instead you are actually initialising the member holdTime from itself (the next nearest "match" for that name), so it only retains its original, unspecified value (and in fact, reading an uninitialised variable results in your program having undefined behaviour).
So, you see, your member variable doesn't "change" at all — you never set it correctly. You'd have known that had you put some diagnostic output inside that constructor to examine the value and see whether it's what you thought it should be. None of the rest of the code was relevant or necessary.
A properly-configured compiler should have warned you about this.

Why do I get an EXC_BAD_ACCESS when reading back a private class variable?

I have a Rectangle class shown below:
Header:
class Rectangle: public Polygon {
private:
float _width, _height;
public:
Rectangle(float width, float height);
float getWidth(float* width) const;
float getHeight(float* height) const;
bool isCollidingWith(Rectangle* other) const;
};
Selected Implementation:
Rectangle::Rectangle(float width, float height) : Polygon(explodeRect(width, height, new struct vertex[4]), 4) {
printf("creating rect %f x %f\n", width, height);
_width = width;
_height = height;
printf("set _width to %f\n", _width);
}
float Rectangle::getWidth(float* width) const {
printf("_w: %f\n", _width);
*width = _width;
return *width;
//return (*width = _width);
}
float Rectangle::getHeight(float* height) const {
return (*height = _height);
}
I initialize an instance of the Rectangle class, and the output indicates that the _width variable is being correctly assigned. However, when I later try to read the variable using the getWidth method, I get an EXC_BAD_ACCESS error on the line:
printf("_w: %f\n", _width);
Why can I no longer read this variable? I get the same problem with the _height variable as well.
EDIT: I would also like to note that if I skip reading the width, I get an error trying to read public variables directly from the object, e.g. when I try to read its x position with obj->x.
EDIT 2: Could this be from the fact that the object is an instance of a subclass of Rectangle, and this subclass is defined in a different file than Rectangle is? I am also reading the values from a third file.
EDIT 3: More code below.
I am trying to re-create Tetris with OpenGL. In my display method, I have this code to draw the rectangles:
if(fallingBlock != nullptr) {
printf("drawing falling block at (%f, %f)\n", fallingBlock->x, fallingBlock->y);
draw(fallingBlock);
}
fallingBlock is defined as a global variable at the top of my file:
Block* fallingBlock;
From my main, I call an initVars method that subsequently calls a startDroppingBlock method. Here it is:
void startDroppingBlock() {
Block* block = availableBlocks[random() % numAvailableBlocks].copy();
block->x = 0.5;
block->y = SCREEN_TOP;
block->dy = -0.01f;
//printf("copied block is at (%f, %f)\n", block->x, block->y);
fallingBlock = block;
}
And here is my block drawing method:
void draw(Block* obj) {
bool shape[3][3];
obj->getShape(shape);
//printf("got shape: {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}\n", shape[0][0], shape[0][1], shape[0][2], shape[1][0], shape[1][1], shape[1][2], shape[2][0], shape[2][1], shape[2][2]);
/*float pieceWidth;
obj->getWidth(&pieceWidth);
pieceWidth /= 3.0f;*/
float pieceWidth = obj->getWidth();
for(unsigned int i=0; i<3; i++) {
for(unsigned int j=0; j<3; j++) {
if(shape[i][j]) {
Square rect = Square(pieceWidth);
rect.x = obj->x + pieceWidth * j;
rect.y = obj->y + pieceWidth * i;
rect.color = obj->color;
draw(&rect);
}
}
}
}
I get an EXC_BAD_ACCESS error on the line [...]. Why can I no longer read this variable? I get the same problem with the _height variable as well. [later...] I have tried both float pieceWidth; obj->getWidth(&pieceWidth); and obj->getWidth(new float) - the actual error is on the line where I read _width, before I even use the passed in pointer. [later...] I modified the getWidth and getHeight methods to just simply return _width and _height. Now I just get an error on return _width;
In this case I see you are using a Rectangle* pointer as obj->getWidth which can as well lead to a bad access error if obj is not a valid pointer.
It is to note that I don't quite understand your getter method at all. A simplified (and possibly standard) version of it might be:
float Rectangle::getWidth() const {
return _width;
}
With the only difference that when you used:
// float a;
// float b;
a = rect.getWidth(&b);
you can now do:
// float a;
// float b;
a = b = rect.getWidth();
which is possibly cleaner and will surely don't cause such an error. A good rule of thumb is never to use pointers when possible. If you need to modify a variable inside a function just use a reference.

Can't pass a string to my class function

I have a class with this function:
void Render(SDL_Surface *source,SDL_Surface *destination,string img)
{
SDL_Rect offset;
offset.x = m_x;
offset.y = m_y;
source = IMG_Load(img);
offset.w = source->w;
offset.h = source->h;
}
For some reason though even with include <string> at the top of the header file it won't allow it. I get:
Identifier, "string" is undefined.
Im passing the data like this on my main file:
btn_quit.Render(menu,screen,"button.png");
When i execute i get :
'Button::Render' : function does not take 3 arguments
But this site says string is the correct syntax for the data type (at the bottom): http://www.cplusplus.com/doc/tutorial/variables/
Can some one explain what I am doing wrong ?
I may suggest you change Render function to below:
void Render(SDL_Surface *source,SDL_Surface *destination,const std::string& img)
{
SDL_Rect offset;
offset.x = m_x;
offset.y = m_y;
source = IMG_Load(img.c_str());
offset.w = source->w;
offset.h = source->h;
}
use std::string instead of string
pass img reference instead of passing by value
change from IMG_Load(img); to IMG_Load(img.c_str());

How can variables be used by a set of classes?

I have a question which I cannot seem to fathom out, as fairly newish to c++. I have a class, in which a set of variables are declared in the .h file and then initialised in the .cpp file. These same variables are used by a set of 3 other classes - and the compiler has them as out of scope. I am not sure how to link the classes so that the variables are visible by all classes. The code itself is a port from a java based language. I am using openFrameworks as my development environment, and I posted my compiler errors on the forum there if it's helpful to have a look http://www.openframeworks.cc/forum/viewtopic.php?f=8&t=4505
smoke.h
#pragma once
#ifndef SMOKE
#define SMOKE
#include "ofMain.h"
#include "VSquare.h"
#include "VBuffer.h"
#include "Particle.h"
#define LWIDTH 151
#define LHEIGHT 11
class Smoke {
public:
int WIDTH;
int HEIGHT;
int RES;
int PENSIZE;
int PNUM;
VSquare v [LWIDTH] [LHEIGHT] ;
VBuffer vbuf [LHEIGHT][LHEIGHT] ;
Particle p [30000];
int pcount;
int mouseXvel;
int mouseYvel;
int randomGust;
int randomGustMax;
float randomGustX;
float randomGustY;
float randomGustSize;
float randomGustXvel;
float randomGustYvel;
Smoke();
void init();
void draw();
};
#endif
The code in my .cpp file looks like this:
#include "Smoke.h"
Smoke::Smoke(){
WIDTH = 300; //these are the variables that go out of scope in all other classes
HEIGHT = 300;
RES = 2;
PENSIZE = 30;
PNUM = 30000;
pcount = 0;
mouseXvel = 0;
mouseYvel = 0;
randomGust = 0;
}
and one of the classes that I have a problem with:
Particle.h
#ifndef PARTICLE
#define PARTICLE
#include "ofMain.h"
class Particle{
public:
float x;
float y;
float xvel;
float yvel;
float temp;
int pos;
Particle(float xIn = 0, float yIn = 0);
void reposition();
void updatepos();
};
#endif
and the .cpp file where the errors are thrown (excerpt):
#include "Particle.h"
Particle::Particle(float xIn, float yIn){
x = xIn;
y = yIn;
}
void Particle::reposition() {
x = WIDTH/2+ofRandom(-20,20); //eg, WIDTH and HEIGHT not declared in this scope
y = ofRandom(HEIGHT-10,HEIGHT);
xvel = ofRandom(-1,1);
yvel = ofRandom(-1,1);
}
void Particle::updatepos() {
int vi = (int)(x/RES); //RES also not declared in this scope
int vu = (int)(y/RES);
if(vi > 0 && vi < LWIDTH && vu > 0 && vu < LHEIGHT) {
v[vi][vu].addcolour(2);
//and so on...
Really hoping this is something that folks can help me figure out! Thanks so much
If the WIDTH and HEIGHT are supposed to be constants, you can move them out of Smoke and just declare them as constants: const int WIDTH = 300; If they need to be members of Smoke but are still constants, then just declare them as static const int WIDTH = 300 then #include "Smoke.h" in your Particle.cpp and reference it as Smoke::WIDTH. This is like a public static variable in Java. If each Smoke object needs its own width, then you need to tell the Particle object which Smoke it needs, or pass in the WIDTH and HEIGHT to the Particle constructor.
The variables are declared within the scope of the Smoke class, so a) they're not global and b) you'll need an instance of a Smoke object in order to get your hands on them. You'd need to #include "Smoke.h", and create / obtain an instance of a Smoke object and then use e.g. mySmoke.WIDTH.
If you want the variables to be 'global' then you need to declare them outside of the scope of the Smoke class - but you'll still need to #include the relevant header.
An instance of the Smoke class will be needed if you would like to access WIDTH AND HEIGHT as they are currently defined because they are part of the smoke class.
Change your method to receive a Smoke instance and then use it in the method as follows:
void Particle::reposition(Smoke& smoke) {
x = smoke.WIDTH/2+ofRandom(-20,20); //eg, WIDTH and HEIGHT not declared in this scope
y = ofRandom(smoke.HEIGHT-10, smoke.HEIGHT);
xvel = ofRandom(-1,1);
yvel = ofRandom(-1,1);
}
int main() {
Smoke smoke;
Particle particle;
particle.reposition(smoke);
}