I'm writing c++ project, which contains several classes. I created .h file named Position.h, with one array and one function:
class Position
{
public:
Coord positions[25];
public:
void setPos(int index, double x, double y)
{
positions[index].x = x;
positions[index].y = y;
}
};
I want to set values in this array from another classes, so every class in this project will see the same values.
I included "Position.h" in other classes, but i can't access the "positions" array.
Anyone can help me plz??
Just chnage the statement :
Coord positions[25];
to
static Coord positions[25];
also change void setPos
to
static void setPos
while accesing the array ,access it as:
Position::positions[any value]
But before accessing the array,make sure you call the function setPos
positions is a member variable associated with a class instance, and therefore not a global. You can make it similar to a global by making it static. Doing so, it will become a class-scoped variable, and not bound to an instance.
You will need to define it in a single implementation file.
An even better alternative would be having an std::vector<Coord>.
As suggested by others, you can make the members static.
You can also create an instance of the Position class as a global variable, and use that:
Position globalPosition;
void function_using_position()
{
globalPosition.setPos(0, 1, 2);
}
int main()
{
function_using_position();
}
Or make it a local variable, and pass it around as a reference:
void function_using_position(Position &position)
{
position.setPos(0, 1, 2);
}
int main()
{
Position localPosition;
function_using_position(localPosition);
}
Related
I have many function definitions which I have placed in different cpp files with function declarations in their respective .h files.
I have a set of a variables which I have placed in a .h file. These variables need to modified by different functions. I am using static to keep the changes from each function, but I heard it is a bad coding practice. How else to do it ? For eg -
variables.h
class variable{
static int x;
static int y;
};
function1.h
class function(){
public:
void function1();
}
similar for function 2
function 1.cpp
void function1(){
// does something with x and y (used as (variable::x=2;variable::y=3)
}
function2.cpp
void function2(){
// does something with x and y (used as variable::x+=2;variable::y+=2)
}
main.cpp
int variable::x;
int variable::y;
int main(){
obj.function1(); (obj is object of function1 class)
obj2.function2(); (obj2 is object of function2 class)
cout << variable::x << variable::y << endl;
}
I was was using different objects in different cpp files but changes in one function were not reflecting in other. How it use it please help?
You can simply move these variables into another class:
struct Shared {
int x;
int y;
};
Now you can pass an instance to this class as parameter to your function, this is called dependency injection:
void foo(Shared& shared) {
shared.x = 4;
shared.y = 2;
}
This is better because you don't have any global state anymore. You could use the function multiple times independent from each other by referencing a different instance of the Shared class.
It is very common to take this a step further by "injecting" the instance in the constructor of that class. This is helpful if the instance of that class should always reference the same instance:
struct Foo {
Shared& m_shared;
Foo(Shared& shared)
: m_shared(shared)
{
}
void foo() {
m_shared.x = 4;
m_shared.y = 2;
}
};
Yes, as you mentioned using static variable for this purpose is kind of anti-pattern. A better pattern (without knowing the background of the application) is using a composition pattern. If your functions f1() and f2() are in classes C1 and C2, you would e. g. create an additional data object D1 (with the variables in question), and inject and object of D1 in the constructor of C1 and C2, so both classes operation on a data object. There are also other solutions to this situation, but I guess thats the most general. Google for C++ Design Pattern to find more general patterns.
You can use smart pointers for global objects
struct MyGlobal
{
std::shared_ptr<Core> core;
MyGlobal(){ core=std::make_shared<Core>(); }
void changeVariableX(int X)
{
core->X = X;
}
};
You can move, copy, do whatever you want with MyGlobal instances and they still point to same core item. Just make sure all of them are populated from same instance like this:
int main()
{
MyGlobal global;
auto something = useSomeFunctionWith(global);
auto somethingElse = useAnotherFunctionWith(global);
...
// use something and somethingElse to change X, both point to the same X
}
If functions will not be thread-safe then you should add a lock-guard into changeVariableX method.
In C++ is it possible to change the default values of a class so that all future objects made of that class will have the values specified?
I am trying to make a class that is user-defined at run time that should function nearly identical to other child of the same parent class, but I am struggling with a way to have the same format constructor exist across both. The only way I can think to properly funnel the correct information to every new object is to have either the class type be always treated differently on creation (always put in the user inputs into the constructor) or have the class's object behavior on creation change to default to the inputs defined.
Edit: To better explain the issue and address the XY problem possibility here is the scenario:
General Program:
I want to have the user first define a custom shape by providing a name and the number of lines that define it. The user then can add triangles, squares and the custom shape to their "cart". Each custom shape is the same shape that they specified at the start, the user does not change it during the program. The program could then return general information such as the number of members of a specific type that exists or the total number of lines in the cart.
There is a parent class:
Class Shape
member numLines, name;
And three classes are children of Shape:
Class Triangle
overwritten numLines = 3, name = "triangle";
...
Class userShape
overwritten numline = ????, name = ????;
When I create methods for the cart that interact with "shape" objects I would like to be able to have the same code across the board for creating additional objects, instead of needing to treat the userShape's constructor differently.
From the answers I have received, the static type seems to best fit the user-setting of the default values but I am entirely open to better ways to implement something like this.
Just because you can, doesn't mean you should. Now that I got that out of the way, here's how:
#include <iostream>
struct C {
static int default_val;
C(int i = default_val) {
std::cout << i << '\n';
}
};
int C::default_val = 0;
int main() {
C c;
C::default_val = 1;
C c2;
return 0;
}
A default argument to a function doesn't have to be a constant expression, it just has to be "available" at every place the function is called. And a static variable is just that.
It also doesn't have to be accessible at the call site. So if you want the class to control it, but not have it be modifiable from outside the class, you can make it private.
I would recommend following the next pattern:
Run your application
Read/Load the configuration
Create a factory for that object from that configuration
Use the factory to create more instances of the same object throught the lifetime of your application
For example:
struct Object {
Object(int x, int y) : _x(x), _y(y) {}
int _x, _y;
};
struct DynamicFactory {
DynamicFactory(int x, int y) : _x(x), _y(y) {}
std::shared_ptr<Object> generate() { return std::make_shared<Object>(_x, _y); }
int _x, _y;
};
int main(){
// Load configuration
// Initialize dynamic factory using configuration
DynamicFactory factory(1, 3);
// Generate objects
auto obj1 = factory.generate();
auto obj2 = factory.generate();
return 0;
}
Try to use static members so these are shared across the objects.
I've been trying desperately to get share a public variable between two classes in C++, but I can't seem to get the hang of it. I've tried getters and setters and calling it directly as a static variable but nothing.
This is what I've tried:
DataGrabber.h
#pragma once
class DataGrabber {
public:
static float temp;
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber::temp;
}
AND THEN THIS:
DataGrabber.h
#pragma once
class DataGrabber {
public:
float temp;
float get(){return temp;}
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber.get();
}
They are both being #include in another main header, testApp.h.
What is the exact problem? How do you use these classes?
Regardless, there are several problems with your getter code.
First, why do you use getter if you make the variable public? If you are going for this design, you should hide the variable as private, to protect it from direct modification.
Second, if it is a simple member variable, you should access it through an object that you pass to your function:
void update(DataGrabber& grabber) {
float x = grabber.get();
}
In this case, you would have to create this object in your main code, which you have not shown.
If you want to use a static variable instead, take a look at a Singleton pattern, but I would advise against it unless there are no better options for your exact problem.
Finally, you should #include all direct dependencies in your header files. Your Particle depends on DataGrabber, so you should include its header from Particle.h. Or, at least, you should add a forward declaration.
I'm writing a library where the user can define arbitrary structures and pass them to my library, which will then obtain the memory layout of the structure from a static member such structure must have as a convention.
For example:
struct CubeVertex {
// This is, per convention, required in each structure to describe itself
static const VertexElement Elements[];
float x, y, z;
float u, v;
};
const VertexElement CubeVertex::Elements[] = {
VertexElement("Position", VertexElementType::Float3),
VertexElement("TextureCoordinates", VertexElementType::Float2),
};
C++ best practices would suggest that I move the static variable and its initialization into my source (.cpp) file. I, however, want to keep the variable initialization as close to the structure as possible since whenever the structure changes, the variable has to be updated as well.
Is there a portable (= MSVC + GCC at least) way to declare such a variable inside the header file without causing ambiguous symbol / redefinition errors from the linker?
Consider a simple getter.
struct CubeVertex {
static const std::array<VertexElement, N>& GetElements() {
static const std::array<VertexElement, N> result = {
//..
};
return result;
}
//..
}
Immediate benefit: No array-to-pointer-decay.
What you could do here is using an anonymous namespace.
Wrap everything into "namespace { ... };" and you can then access CubeVertex::Elements like you normally do.
However, this creates a new instance of the static data everytime you include the headerfile, which adds to the executable's filesize.
It also has some limitations on how to use the class/struct, because you cannot call functions of that class from another file (which won't be a problem in this special case here).
I'm creating a minimal circle-circle physics engine in a static library, and I've came across a problem. I have a header file for object manipulation, one of the variables is the objects position. The position variable is declared in bpObject.h, and I have a void function, SetPosition(), that accesses the current position and sets its to the parameters specified (also declared in bpObject.h). My problem is that in the source file, I need to access the position variable (private). I can't access it through the bpObject class, because, being a class, it won't have the correct value when it is used as a type. So, how would I access the position variable within the class?
Thanks in advance,
Greg Treleaven
EDIT
Code for bpObject.h
#include "bpMath.h"
namespace bp
{
class Object
{
private:
static bp::Vector position;
static bp::Vector velocity;
static bp::Vector acceleration;
public:
static single restitution;
static single radius;
static void setPosition(single X, single Y);
static bp::Vector getPosition();
static void applyPosition(single X, single Y);
static void setVelocity(single X, single Y);
static bp::Vector getVelocity();
static void applyVelocity(single X, single Y);
static void setAcceleration(single X, single Y);
static bp::Vector getAcceleration();
static void applyAcceleration(single X, single Y);
}
}
I'm guessing you don't actually want all those 'static's in there, is your first problem (as it stands, you pretty much can only access a single object)
Once you get rid of those, you can implement SetPosition in your source file by:
namespace bp {
void Object::SetPosition(single X, single Y) {
position[0] = X; //or however your bp::Vector is implemented
position[1] = Y;
}
}
Yes, position is private, but when you actually define the method, you get to access the members. Is this at all what you are asking?
You're asking the wrong question. If, as you say, the variable doesn't have the correct value when it's needed, then the problem has nothing to do with access methods or public/private.
How is the variable supposed to get its proper value? Something must call setPosition, so you have to arrange things so that this happens before anything else needs that value.
Once you have that, your accessors (setPosition and getPosition) should work just fine (after you get rid of the static, which makes no sense).