C++ Using classes in other classes failing - c++

I have a Display class that uses SDL to write pixels to the screen. I'd like another class (Triangle) to be able to use this already existent class object, so I've been trying to pass the object by address.
It's sort of working, in the sense that it is actually calling the methods. However, I was getting a segmentation fault in the DrawPixel function. After checking gdb and checking what values are in the function, I figured out that the color_buffer array does not exist (note that when DrawPixel is called directly from the display class in main it works fine).
After a little more testing, I determined that window_width, window_height etc are not set in the Triangle's version of the Display object. But they do exist in the original Display object.
So I'm assuming that I am not properly passing in my object, but I'm uncertain how to fix this issue as I thought passing by address would work just fine. How can I pass an already existing/instantiated class to another class?
I've also tried putting color_buffer into public variables in case private was causing it, but that didn't help.
Example:
main.cpp
int main() {
Display display;
Triangle triangle(&display);
// This doesn't work
triangle.DrawTriangle(300, 500, 0xFFFFFF00);
// This does work
display.DrawPixel(300, 500, 0xFFFFFF00);
return 0;
}
triangle.hpp
class Triangle {
private:
Display* display;
public:
DrawTriangle(int x, int y, uint32_t color);
};
triangle.cpp
Triangle::Triangle(Display* display) {
display=display;
}
Triangle::DrawTriangle(int x, int y, uint32_t color) {
display->DrawPixel(x, y, color);
}
display.hpp
class Display {
private:
// SDL Stuff defined here
uint32_t* color_buffer;
int window_width = 1920;
int window_height = 1080;
public:
Display();
DrawPixel(int x, int y, uint32_t color);
};
display.cpp
Display::Display() {
// SDL Stuff declared
color_buffer = new uint32_t[window_width * window_height];
}
Display::DrawPixel(int x, int y, uint32_t color) {
// This is receiving the correct values, but doesn't allow me to access
// any index of color_buffer.
color_buffer[(y * window_width) + x] = color;
}

Triangle::Triangle(Display* display) {
display=display;
}
the display is not the member of your class.Use this->display = display instead

You have to use "this" in Triangle constructor. That should solve the problem.
Triangle(Display* display) {
this->display=display;
}

A couple of things to add to the answers above:
use a different naming convention for member variables - this way it is very easy to avoid typos. _display, m_display, Display_ (Clang style =) )
class members are private by default so if you are following convention where attributes are defined on top, there's no need to add private:
Some prefer references (e.g. Display&), mostly to save typing ->, since if `Display goes out of scope it will have the same hilarious effect as passing a pointer.
static analyzers look down on pointer arithmetic(due to possible out-of-bounds writes).
You can use std::array from header:
static constexpr int WIDTH = 1920;
static constexpr int HEIGHT = 1080;
std::array<uint32_t, WIDTH* HEIGHT> m_color_buffer{};
and then either use m_color_buffer[index] = color (no bounds checking, random memory gets written if you write out of bounds in release and normally an exception in debug), or use m_color_buffer.at(index) - slower but this way you get an exception in release mode, but the compiler may complain about the stack size, as the definition is essentially the same as uint32_t buffer[WIDTH*HEIGHT]. std::vector is a better alternative - it hides buffer allocation, manages memory (no need to delete) at expense of the 2 extra pointers for begin and the end of the vector.
The code example lacked a destructor. Every new should have an accompanying delete hence either add it or just switch to a standard library container to avoid the headache =)
Last but not least - both classes override constructors. Display also manages resources. What happens when you copy Display instances? Move them? It is a bit of a headache and leads to a bit of a boilerplate, but it is best to implement Rule of 5 members and avoid accidental surprises =)
PS. C++ is a beautiful language =)

Related

How do I assign to a const variable using an out parameter in C++?

In a class header file Texture.h I declare a static const int.
static const int MAX_TEXTURE_SLOTS;
In Texture.cpp I define the variable as 0.
const int Texture::MAX_TEXTURE_SLOTS = 0;
Now in Window.cpp class's constructor I attempt to assign to the variable using an out parameter, however this obviously does not compile as &Texture::MAX_TEXTURE_SLOTS points to a const int* and not an int* .
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &Texture::MAX_TEXTURE_SLOTS);
I have tried using const_cast, but am greeted with a segmentation fault on runtime.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, const_cast<int*>(&Texture::MAX_TEXTURE_SLOTS));
I have also tried directly casting to an int * but once again, seg fault.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int*)&Texture::MAX_TEXTURE_SLOTS);
Many thanks.
EDIT 2: So since you're trying to abstract OpenGL contexts, you'll have to let go of the "traditional" constructor/destructor idioms. And just for your information (unrelated to this question): OpenGL contexts are not tied to windows! As long as a set of windows and OpenGL contexts are compatible with each other, you may mix and match any way you like. But I digress.
The standard idiom to deal with a situation like yours is to use preinitializing factory functions. Like this:
class MyOpenGLContextWrapper {
public:
// Yes, shared_ptr; using a unique_ptr here for objects that are kind
// of a nexus for other things -- like an OpenGL context -- just creates
// a lot of pain and misery. Trust me, I know what I'm talkink about.
typedef std::shared_ptr<MyOpenGLContextWrapper> ptr;
struct constdata {
NativeGLContextType context;
// ...
GLint max_texture_image_units;
// ...
};
static ptr create();
protected:
MyOpenGLContextWrapper(constdata const &cdata) : c(cdata) {};
virtual ~MyOpenGLContextWrapper();
constdata const c;
}
MyOpenGLContextWrapper::ptr MyOpenGLContextWrapper::create()
{
struct object : public MyOpenGLContextWrapper {
object(MyOpenGLContextWrapper::constdata const &cdata) : MyOpenGLContextWrapper(cdata) {}
~object(){}
};
MyOpenGLContextWrapper::constdata cdata = {};
// of course this should all also do error checking and failure rollbacks
cdata.context = create_opengl_context();
bind_opengl_context(cdata.context);
// ...
glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, &cdata.max_texture_image_units);
return std::make_shared<object>(cdata);
}
EDIT: I just saw that you intend to use this to hold on to a OpenGL limit. In that case you can't do this on a global scope anyway, since those values depend on the OpenGL context in use. A process may have several OpenGL contexts, each with different limits.
On most computer systems you'll encounter these days, variables declared const in global scope will be placed in memory that has been marked as read only. You literally can't assign to such a variable.
The usual approach to implement global scope runtime constants is by means of query functions that will return from an internal or otherwise concealed or protected value. Like
// header.h
int runtime_constant();
#define RUNTIME_CONSTANT runtime_constant()
// implementation.c / .cpp
int runtime_constant_query(){
static int x = 0;
// NOTE: This is not thread safe!
if( !x ){ x = determine_value(); }
return x;
}
You can then fetch the value by calling that function.
Provided that glGetIntegerv doesn't depend on other gl* functions being called before, you may use an immediately-invoked lambda:
// Texture.cpp
const int Texture::MAX_TEXTURE_SLOTS = []
{
int maxTextureSlots{0}:
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureSlots);
return maxTextureSlots;
}();
You don't.
You can't assign to a const outside of its definition. Also, using a const variable where the const has been const_casted away is UB. This also means you can't directly initialize a const variable with an output parameter. For trivial types, just output to another variable and make a const copy if you so wish.
If you were the author of the function you're calling, you would do well not to use out parameters, and then you could assign to const variables directly, perhaps using structured bindings if you want to name multiple of the outputs at a time. But here, you're not.

Class method being called in main, changes don't persist outside class method?

Basically, I have two classes, Peg and Disk. (It's a Towers of Hanoi program) The files I have are Disk.h, Disk.cpp, Peg.h, Peg.cpp, and main.cpp. Not sure if that matters. Here's the disk class from Disk.h
#include <vector>
#include "gwindow.h"
#ifndef DISK_H
#define DISK_H
class Disk
{
private:
int xCoord; //x and y coords are for drawing in a gwindow
int yCoord;
int mHeight;
int mWidth;
COLOR mColor;
int mName; //helps me keep track of which is which
public:
Disk(); //default constructor
Disk(int x, int y, int heightIn, int widthIn, COLOR colorIn);
void setXY(int x, int y); //this is the one I'm having trouble with
int getHeight();
int getWidth();
int getX();
int getY();
COLOR getColor();
std::string diskColor();
void draw(GWindow &gw);
void nameDisk(int name); //yet this one is working?
int getName();
};
#endif
However, I'm having trouble with the setXY function. When I call it from main, it calls the function properly, changes the variable inside the scope of setXY, but the value doesn't persist outside the function. However, nameDisk works fine and is basically the same thing, except it is changing mName instead of xCoord and yCoord. Here is setXY:
void Disk::setXY(int x, int y)
{
xCoord = x;
yCoord= y;
}
and here is how I call it from main:
pegVec[2].getDisks()[0].setXY(690, 200);
I know this looks crazy, but basically pegVec is a vector of 3 peg objects. Each peg object has a function, getDisks(), which returns a vector of all the disks on that peg currently. So the line above is trying to perform setXY on the first peg on peg 2. Sorry if that's unclear, but I've tried making a new disk object and calling it on that and that didn't work either.
Here is getDisks, if it matters:
std::vector<Disk> Peg::getDisks()
{
return disksOn;
}
and disksOn is just a member variable of Peg:
std::vector<Disk> disksOn;
I think it might be a problem with how getDisks() works. I'm a noob, but I'm guessing that returning the vector disksOn makes a "copy" of it, kind of, which is what I am altering with my setXY function but which is not the same as the actual disksOn vector associated with the Peg object? I don't know if that makes sense.
What I've tried so far:
Making xCoord and yCoord public variables and updating them manually instead of making a setter function. This did not work.
I printed out the x and y values at every step. Inside setXY, the values were updated successfully, but when the function ended they went back to how they were.
I tried some mess with the const keyword, but I don't understand it and couldn't even get it to run.
Passing everything by reference/value
Making a new function in main which accepted a Disk vector as input, and using getDisks as input to that function. Didn't work, same problems.
Tested my other setter function, nameDisk, which works fine. It's essentially the same as setXY, which is why I think the problem is with getDisks.
Using pointers at various points (heh) throughout, but I wasn't sure the best way to do that. I was messing with it last night so I don't remember 100% but I think I tried to have getDisks return a pointer instead of the vector, and I don't think that worked, but it's more likely a problem with my syntax and how I used the pointer. I think that might work but I don't know how to shake it.
Help?
You're on the right track - somehow you're looking at a different objects than what you think you are. Using references is a good solution, but you may not have got the right one ;-)
Try:
// Return reference to the disks on the peg.
std::vector<Disk>& Peg::getDisks()
{
return disksOn;
}
The issue is that
std::vector<Disk> getDisks() { return disksOn; }
returns a completely new and separate temporary copy of disksOn rather than a reference to the original. So you're modifying a temporary copy which gets discarded at the end of the statement.
You need to use
std::vector<Disk> &getDisks() { return disksOn; } in order to return a reference to disksOn.
Although if you are going to return a reference to the vector member object you might as well make the object directly accessible as public because anyone can manipulate the vector at this point and get rid of the getDisks() function as it serves no purpose in terms of access protection.
Better design would be to give access to individual disks:
Disk &getDisk(int index) {
return disksOn[index];
}
const Disk &getDisk(int index) const {
return disksOn[index];
}
The idea behind not giving direct access to the vector is that you can later change the underlying container type if needed without changing the code outside of the Peg class.
The second version (const) is necessary for accessing const Disks of const Peg objects.

Accessing vector of pointers in a class

I'm trying to figure out a way to keep track of all the instances of a class I have made, so I can access them at any point using a title string (or int ID)
I decided to use a static vector of pointers to each instance, and then on creating each instance i'd add a pointer to it to the vector.
This works up to a point but at one point the values inside each element of the vector seem to reset/get randomly assigned values and i can't figure out what's happening.
i'm adding the object to the vector here:
SWindow::SWindow(LPCWSTR WindowClass, LPCWSTR Title, UINT Style, int x, int y, int height, int width, HWND hParWnd, HINSTANCE hInstance)
:
x(x),
y(y)
{
hWnd = CreateWindowEx(NULL, WindowClass, Title, Style, x, y, height, width, hParWnd, NULL, hInstance, NULL);
SWindows.push_back(this);
The function at which the values change is:
which is a member of the SWindow class
SWindow.h:
static SWindow* GetSWindow(wstring ws);
SWindow.cpp:
SWindow* SWindow::GetSWindow(wstring ws)
{
for (int i = 0; i < SWindow::SWindows.size(); i++)
{
if (SWindows[i]->title == ws)
{
return SWindows[i];
}
else
{
}
}
return 0;
}
i'm accessing the function from a different class using:
SWindow* pPlayViewer = SWindow::GetSWindow(L"Viewer");
Also if this is a bad way to be doing what i am trying to do, let me know of a better way.
Thanks!
Are you sure that you didn't add stack allocated objects into your static vector? Did you remove pointers when objects are deleted ?
If you want to be more efficient, I can suggest you to use a map, where the key can be your title string/id int and the value the pointer, so that the search would be much faster than parsing the whole array.
There are four main possible causes for the dangling pointers:
you do not remove the instances from the vector upon destruction of an instance
you create instances accross DLL boundaries (and pass the vector arround)
you have a buffer overflow (or similar) in another part of the code and it is overwriting your vector
you are accessing the vector concurrently from multiple threads (and the access to it doesn't look synchronized in your code)
(this is all speculation on my part).
To use such a vector correctly, you will have to do the following:
implement all constructors and destructor for your class (this implies you will also implement the assignment operators, according to the rule of five).
ensure all constructors add this to the vector
ensure destructor removes this from the vector
Also, suggested refactorings:
pass the vector into the object, instead of declaring it as static; this will allow you to decide in client code if you have a single vector, multiple ones, or a window manager object of some sort, that holds a vector internally
group the window creation parameters into a structure, and pass that arround as a parameter
your SWindow class wants to be both a window manager and a window; Extract the window management into a separate object

C++ persistence of objects declared within a block, memory leakage possibility?

First of all let me prefix this question with the following points:
1) I have searched Stackexchange for this issue, most of the code presented was difficult enough for me to follow in order to warrant Asking a new Question/Opening a new Thread about this. The closest i could find was this Creating multiple class objects with the same name? c++ and unfortunately this is way past my scope of understanding
2) http://www.cplusplus.com/doc/tutorial/classes/ has not really discussed this or i have missed it.
Now that this is out of the way:
Rectangle Class code:
class Rectangle {
private:
int lineNumber;
float valueMax;
float valueMin;
public:
Rectangle(SCStudyInterfaceRef sc, int lineNumber, float valueMax, float valueMin);
int getLineNumber(); // member function of class
float getValueMax(); // member function of class Rectangle
float getValueMin(); // member function of class Rectangle
};
Rectangle::Rectangle(SCStudyInterfaceRef sc, int lineNumber0, float value1, float value2) {
lineNumber = lineNumber0;
int value2_greater_than_value1 = sc.FormattedEvaluate(value2, sc.BaseGraphValueFormat, GREATER_OPERATOR, value1, sc.BaseGraphValueFormat);
if (value2_greater_than_value1 == 1) {
valueMax = value2;
valueMin = value1;
} else {
valueMax = value1;
valueMin = value2;
}
}
int Rectangle::getLineNumber() {
return lineNumber;
}
float Rectangle::getValueMax() {
return valueMax;
}
float Rectangle::getValueMin() {
return valueMin;
}
And here is the more important part, this code is running pretty much in a loop and will repeat everytime a certain event triggers it:
bool xxx = Conditions here
if (xxx) {
// Draw new rectangle using plattforms code
code here
// Save rectangle information in the list:
Rectangle rect(sc, linenumbr + indexvalue, high, low);
(*p_LowRectanglesList).push_back(rect);
}
bool yyy = conditions here
if (Short) {
// Draw new rectangle using plattforms code
code here
// Save rectangle information in the list:
Rectangle rect(sc, linenumber + indexvalue, high, low);
(*p_HighRectanglesList).push_back(rect);
}
So the question is the following:
Since this is looped everytime an event triggers the second part of the code is going to be run, the bool condition is going to be checked, if its true its going to use plattform integrated code to draw a rectangle. Once it has drawn it this information is going to be passed to a new rectangle object/instance based on the Rectangle Class in the first part of the code using the: Rectangle rect(sc, linenumber + indexvalue, high, low); part and then save that information in a list which is in a different part of the code for now and irrelevant.
What exactly happens when there is a new Bool = True condition and the code gets executed after it has already been executed? Will the old rectangle object be simply replaced with a new rectangle object with the same name and using the new parameters (since they change on every instance due to the way the code is written)? Or are there now two objects of the Rectangle Class using the same name "rect" ?
It's technically speaking not even that important to me since the information of the parameters should be pushed into a list anyways using the (*p_HighRectanglesList).push_back(rect); part of the code
So TL;DR:
Does "rect" get destroyed/overwritten or are there now potentially limitless amounts of Rectangle Objects/Instances called "rect" floating around?
My Apologies for the wall of text but being a complete noob i thought it would be best to outline my thought process so that it will be easier for you to correct me on where I'm wrong.
Kind regards,
Orbital
Yes, rect is destroyed and recreated every loop. In C++, the scope of any variable declared in a block (in this case an if() statement) is limited to that block. Every time your program iterates, you get a new rect, and the old rect is gone.
To add, whenever you call NEW, you are basically allocating memory and creating Rectangle objects. NEW will allocate address to each instance. The pointer *rect will be pointing to the current memory address, and when you call rect with NEW again, now rect will be pointing to the new memory address the previous address becomes a NULL reference. However in C++ you have to worry about memory leaks unlike Java where you have a garbage collector.

Is it better to store class constants in data members or in methods?

I recently wrote a class that renders B-spline curves. These curves are defined by a number of control points. Originally, I had intended to use eight control points, so I added a constant to the class, like so:
class Curve
{
public:
static const int CONTROL_POINT_COUNT = 8;
};
Now I want to extend this class to allow an arbitrary amount of control points. So I want to change this to:
class Curve
{
public:
int getControlPointCount() {return _controlPointCount;}
};
The question is whether it isn't better to store constants in methods to begin with, to facilitate adaptability. In other words, isn't it better to have started thus:
class Curve
{
public:
int getControlPointCount() {return 8;}
};
The advantage of this is that I could have just changed one symbol in the method in question, instead of moving around constants etc.
Is this a good practice or a bad one?
int getControlPointCount() {return _controlPointCount;}
This is an accessor. Swapping a const static for an accessor is not really a gain as litb has pointed out. What you really need to future-proof is probably a pair of accessor and mutator.
int getControlPointCount() {return _controlPointCount;} // accessor
I'd also throw in a design-const for the accessor and make it:
int getControlPointCount() const {return _controlPointCount;} // accessor
and the corresponding:
void setControlPointCount(int cpc) { _controlPointCount = cpc;} //mutator
Now, the big difference with a static object is that the control-point count is no longer a class-level attribute but an instance level one. This is a design change. Do you want it this way?
Nit: Your class level static count is public and hence does not need an accessor.
Typically I favour maintaining as few couplings manually as possible.
The number of control points in the curve is, well, the number of control points in the curve. It's not an independent variable that can be set at will.
So I usually would expose a const standard container reference:
class Curve
{
private:
std::vector<Point>& _controlPoints;
public:
Curve ( const std::vector<Point>& controlPoints) : _controlPoints(controlPoints)
{
}
const std::vector<Point>& getControlPoints ()
{
return _controlPoints;
}
};
And if you want to know how many control points, then use curve.getControlPoints().size(). I'd suspect that in most of the use cases you'd want the points as well as the count anyway, and by exposing a standard container you can use the standard library's iterator idioms and built-in algorithms, rather getting the count and calling a function like getControlPointWithIndex in a loop.
If there really is nothing else in the curve class, I might even go as far as:
typedef std::vector<Point> Curve;
(often a curve won't render itself, as a renderer class can have details about the rendering pipeline, leaving a curve as purely the geometric artifact)
To better answer your question, one should also know how the controlPointCount variable is set. Is it set outside from your class? In this case, you should also define a setter. Or the Curve class is the sole responsible for setting it? Is it set only on compile time or also on runtime.
Anyway, avoid a magic number even in this form:
int getControlPointCount() {return 8;}
This is better:
int getControlPointCount() {return CONTROL_POINT_COUNT;}
A method has the advantage that you can modify the internal implementation (use a constant value, read from a configuration file, alter the value dynamically), without affecting the external of the class.
class Curve
{
private:
int _controlPointCount;
void setControlPointCount(int cpc_arg)
{
_controlPointCount = cpc_arg;
}
public:
curve()
{
_controlPointCount = 8;
}
int getControlPointCount() const
{
return _controlPointCount;
}
};
I will create a code like this, with set function in private, so that no body can play with control point count, until we move to the next phase of development..where we update start to update the control point count at runtime. at that time, we can move this set method from private to public scope.
While understanding the question, I have a number of conceptual problems with the example:
What is the return value for getControlPointCount() when the number of control points is not limited?
Is it MAXINT?
Is it the current number of control points on the curve (thus breaking the logic that says that this is the largest possible number of points?)
What happens when you actually attempt to create a curve with MAXINT points? You will run out of memory eventually.
The interface itself seems problematic to me. Like other standard collection classes, the class should have encapsulated its limitation on number of points, and its AddControlPoint() should have returned an error if a limitation on size, memory, or any other violation has occurred.
As for the specific answer, I agree with kgiannakakis: a member function allows more flexibility.
I tend to use configuration + constant (default value) for all 'stable' values through the execution of the program. With plain constants for values that cannot change (360 degrees -> 2 pi radians, 60 seconds -> 1 minute) or whose change would break the running code (minimum/maximum values for algorithms that make them unstable).
You are dealing with some different design issues. First you must know whether the number of control points is a class or instance level value. Then whether it is a constant at any of the two levels.
If all curves must share the same number of control points in your application then it is a class level (static) value. If different curves can have different number of control points then it is not a class level value, but rather a instance level one.
In this case, if the number of control points will be constant during the whole life of the curve then it is a instance level constant, if it can change then it is not constant at this level either.
// Assuming that different curves can have different
// number of control points, but that the value cannot
// change dynamically for a curve.
class Curve
{
public:
explicit Curve( int control_points )
: control_points_( control_points )
{}
// ...
private:
const int control_points_;
};
namespace constant
{
const int spline_control_points = 8;
}
class Config
{
public:
Config();
void readFile( std::string const & file );
// returns the configured value for SplineControlPoints or
// constant::spline_control_points if the option does not
// appear in config.
int getSplineControlPoints() const;
};
int main()
{
Config config;
config.readFile( "~/.configuration" ); // read config
Curve c( config.getSplineControlPoints() );
}
For integral type I'm usualy using:
class Curve
{
public:
enum
{
CONTROL_POINT_COUNT = 8
};
};
If constant doesn't need for any entities except class implementation I declare constants in *.cpp file.
namespace
{
const int CONTROL_POINT_COUNT = 8;
}
In general, all your data should be private and accessed via getters and setters. Otherwise you violate encapsulation. Namely, if you expose the underlying data you lock yourself and your class into a particular representation of that underlying data.
In this specific case I would have done the something like the following I think:
class Curve
{
protected:
int getControlPointCount() {return _controlPointCount;}
int setControlPointCount(int c) { _controlPointCount = c; }
private:
static int _controlPointCount = 0;
};
Constants in general should not be defined inside methods. The example you're choosing has two unique features. First, it's a getter; second, the type being returned is an int. But the point of defining constants is to use them more than once, and to be able to refer to them in a convenient way. Typing "8" as opposed to "controlPointCount" may save you time, and may not seem to incur a maintenance cost, but this won't typically be true if you always define constants inside methods.