How to make a class variable in one line? - c++

In C++ how make a class variable in one line?
For example:
I have a class:
class point{
public:
int x;
int y;
};
How to make a variable in one line like java you can do new point(x, y), currently I do make a tmp and then push back to vector or something, are the simply way like java can do what I do in one line?

For creating a variable of type point on the stack you can use:
point myVariable{5,6};//this creates a point type variable on stack with x=5 and y=6;
So the complete program would look like:
#include <iostream>
class point{
public:
int x;
int y;
};
int main()
{
point myVariable{5,6};
return 0;
}
The output of the above program can be seen here.
If you want to create a vector of point objects and then add objects into it, then you can use:
//create point objects
point p1{5,6};
point p2{7,8};
//create a vector
std::vector<point> myVector;
//add p1 and p2 into the vector
myVector.push_back(p1);
myVector.push_back(p2);

Build a constructor Point(int x, int y) : x(x), y(y) {}
And then push to vector as usual vec.push_back(Point(x,y))

Related

C++ Classes, Pointers, Constructors, Segmentation Faults, 2D arrays

.h file
public:
Class(int x, int y); //constructor for this question
private:
char (*1dArrayObjectPtr)[size] = nullptr;
char nameof2dArray[notImportantX][size];
What is the difference between initializing Class (*1dArrayObjectPtr)[size] = nullptr; then assigning by:
cpp file
Class::Class(int x, int y) : x(x), y(y) {1dArrayObjectPtr = nameOf2dArray;};
or:
Class::Class(int x, int y) : x(x), y(y), 1DArrayObjectPtr(nameof2dArray) {};
Why does the top option result in segmentation faults and the bottom does not when I access as:
*(*(1DArrayObjectPtr+i)+j)
or
1DArrayObject[i][j]
If I pass 1DArrayObjectPtr to a new class will I be able to iterate the same?:
newClass::newClass(char* 1DArrayObjectPtr) : newClassPtr(1DArrayObjectPtr) {};
iterate as *(*(newClassPtr+i)+j) or newClassPtr[i][j]
Or am I changing the 1dpointer from the 2D array into something else and not realizing?
Scheff has confirmed semantically, there is no difference. I will look to my constructors for the base class to see if they could be culprit. Thanks Scheff. I tried to mark your comment as a solution, but I may have flagged it by mistake.... :D

How is implemented this function foo.getSize().x

Recently I've start learning sfml graphics and I saw this kind of functions window.getSize().x or .y, my question is how can I write such a function, more exactly to use .x or .y on an object function?
Those functions return a vector object that have the variables x and y internally.
Something kinda like this
template<typename T>
struct Vec2
{
T x, y;
Vec2(T x, T y)
: x(x), y(y)
};
class Window
{
public:
Vec2<unsigned int> getSize()
{
return size;
}
private:
Vec2<unsigned int> size;
};
This is only a simple example but it should show you how it works.
to use .x or .y on an object function?
This seems to indicate a misunderstanding of the syntax. The .x and .y are not being applied to the function. Rather, they are applied to the value returned by the function.
In this case, sf::Window::getSize() returns a sf::Vector2u. The sf::Vector2u class has two public attributes, x and y. Writing
unsigned value = window.getSize().x;
is (concise and) equivalent to writing (more verbosely)
sf::Vector2u size = window.getSize();
unsigned value = size.x;
The function does not define .x; the class does.

Segmentation fault when using vectors in the class and constructor

I was doing a list of programming projects, and this project is to make a 15 puzzle (slide puzzle). I was working on the project when I hit a small roadblock.
My code compiles just fine, but when I run it, I get a segmentation fault at line 12: pos[0] = x;
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos[0] = x;
pos[1] = y;
value = value_;
}
~Tile(){}
int getPos(int a){return pos[a];}
void setPos(int a, int b){pos[a] = b;}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}
I mean, I could just do the whole project without having to use vectors/arrays to handle the position, but I do still want to know, for my own understanding in the future, why this doesn't work.
Based on the debug that I ran, the program is having trouble initializing the value of the pos[] vector.
Another issue: probably related, I tried setting the size of the vector when it was instantiated.
vector<int> pos(2);
But then I get the debug error:
error: expected identifier before numeric constant
Not sure whats going on here. I've tried a bunch of different things but I can't seem to figure out why my vectors don't work inside of classes.
I'm sure there are a hundred ways I could have done this little piece better, and I would love to know how you would have fixed it, but I also need to know what is wrong, specifically in the context of what I have written and tried.
Thanks.
I tried setting the size of the vector when it was instantiated.
vector<int> pos(2);
But then I get the debug error:
error: expected identifier before numeric constant
That's a compilation error, not a debug error.
You can't initialise members like that. However, you can (and should) initialise them using the parent constructor:
Tile(int x, int y, int value_)
: pos(2)
{
pos[0] = x;
pos[1] = y;
value = value_;
}
Currently you're just leaving your vector empty then accessing (and writing to!) elements that don't exist.
You really don't want a vector for this, anyway: that's a lot of dynamic allocation. How about a nice array? Or just two ints.
As mentioned in other answers, your vector is empty and your code is attempting to assign non-existent elements.
The solution is to always use initialisers instead of assignment. Rewrite your constructor as follows:
Tile(int x, int y, int value) :
pos{x, y},
value{value} {}
Note that the constructor body is now empty. All initialisation happens where it should — in the initialiser list.
Apart from that, your class does not need an explicitly defined destructor; the default destructor works just fine.
There are other issues with this class — for instance, what happens when the user does tile.setPos(3, 4)? A rule of thumb of good API design is to make it impossible to misuse the API.
Here’s how I would write your Tile class instead:
struct Tile {
int x;
int y;
int value;
Tile(int x, int y, int value) : x{x}, y{y}, value{value} {}
};
The getter and setter in your case wasn’t really doing any meaningful work. There’s an argument to be made to hide all data members behind accessors to future-proof access control. I’m no longer convinced this is actually useful but just in case, here’s a solution with that, too:
class Tile {
int x_;
int y_;
int value_;
public:
Tile(int x, int y, int value) : x_{x}, y_{y}, value_{value} {}
int x() const { return x; }
int& x() { return x; }
int y() const { return y; }
int& y() { return y; }
int value() const { return value; }
};
This makes x and y readable and writable (via assignment: t.x() = 42;), and value only readable. Other APIs are possible, with different sets of trade-offs. The important thing is to be consistent.
Your constructor doesn't set the size, so when you try to access/modify its contents, you are probably getting the exception.
Tile(int x, int y, int value_) : pos(2) {
pos[0] = x;
pos[1] = y;
value = value_;
}
You can use the initialization list of the constructor to call the vector's constructor, as in the code above.
There are couple of issue in the given code, which I have resolved and added comment in the code.
Issue in setPos and getPos might raise segmentation fault must be handle.
Added checks for the same.
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Tile{
private:
vector<int> pos;
int value;
public:
Tile(int x, int y, int value_){
pos.push_back(x); // this is equivalent to pos[0] = x, in this case
pos.push_back(y); // this is equivalent to pos[0] = y, in this case
value = value_;
}
~Tile(){}
int getPos(int a){
if(a >= pos.size()){
return -1; // if a is greater than size then pos[a] will raise the segmentation fault
}
return pos[a];
}
void setPos(int a, int b){
if(a >= pos.size()){
pos.resize(a+1); // to avoid segmentation fault, we are increasing the size if the given index is higher
// resize initialise the value with 0 as default value.
}
pos[a] = b;
}
};
int main(){
Tile tile1(1, 2, 10);
Tile* t1;
t1 = &tile1;
// returns position "x"
cout << t1->getPos(0);
return 0;
}

how do i assign value to member variable of type std::map<std::string,shared_ptr<A>>

i'm 1st time trying boost lib and don't know how to assign map of string and share pointer.
here is my code and i'm trying to assign value but not able to do it.
#include <boost\shared_ptr.hpp>
#include <boost\assign.hpp>
#include <boost\map.hpp>
struct X
{
public:
int p;
double q;
X();
~X();
};
struct Y
{
float m;
double n;
Y();
~Y();
};
struct Z
{
public:
std::map<std::string,boost::shared_ptr<X>> Xtype;
std::map<std::string,boost::shared_ptr<Y>> Ytype;
int i;
string name;
Z();
~Z();
};
struct X *x1;
struct Y *y1;
void setx()
{
x1->p=10;
x1->q=20.20;
}
void sety()
{
y1->m=10;
y1->n=20.20;
};
void initialize(Z *z1)
{
z1->i=30;
// how to i add x1 and y1 to Xtype and Ytype respectively of z1 struct
}
my question :- how do i assign x1 and y1 value to Xtype and Ytype of z1 type.
really do not know what to do and how to start. If i'm able to assign then i can move ahead to do serialization of it.
just use the [] operator:
std::map<std::string, some_type> my_map;
some_type object=get_object(); // an object that you want to insert into the map
std::string key=get_key(); // the key you want to associated with object
assert(my_map.empty()); // no keys in map yet! (only for demonstration)
my_map[key] = object;
If the map already contains the key provided, than the object for that key is replaced. Otherwise, a new entry into the map is generated and initialised with the object. Read more about std::map here (and avoid using shared_ptr<> if you don't know it yet and aren't 200% sure it's needed).

a nicer way to create structs in a loop

I haven't coded in C++ in ages. And recently, I'm trying to work on something
involving structs. Like this
typedef struct{
int x;
int y;
} Point;
Then in a loop, I'm trying to create new structs and put pointers to them them in a list.
Point* p;
int i, j;
while (condition){
// compute values for i and j with some function...
p = new Point;
p* = {i, j}; //initialize my struct.
list.append(p); //append this pointer to my list.
}
Now, my question is it possible to simplify this? I mean, the pointer
variable *p outside of the loop and calling p = new Point inside the loop.
Isn't there a better/nicer syntax for this?
Sure:
Point * p = new Point;
You should probably also give your Point class a constructor:
struct Point { // note no need for typedef
int x;
int y;
Point( int ax, int ay ) : x( ax ), y( ay ) {}
};
so that you can say:
Point * p = new Point( i, j );
You may also want to make your list a list of Point values, rather than pointers, in which case you can avoid using dynamic allocation with new - always something to be avoided wherever possible in C++.
The struct can have a constructor like:
struct Point{
Point(int ax, int ay):x(ax), y(ay){}
int x;
int y;
};
and then the function can look like:
int i, j;
while (condition)
{
list.append(new Point(i,j));
}
As structs are classes with public members by default, you could even create a constructor within the struct and initialize your point object within the loop like this:
Point* p = new Point(i,j);
I would venture a guess that it is extremely unlikely you really need to allocate something like a Point dynamically.
Most likely you want to add a constructor and store them by value:
list<Point> list;
list.append(Point(x, y));
I recommend the Factory approach. Assuming that "Point" will be the base class of many objects, you can have a "Factory" that would return pointers.
Ex:
struct Point
{
Point(int mx, int my):x(mx),y(my) {}
int x;
int y;
};
// Circle, Polygon, etc.
class Factory
{
public:
static Point *getPoint(int mx, int my) { return new Point(mx, my); }
// Circle, Polygon, etc
};
Then in code someplace:
while(cond)
{
list.append(Factory::getPoint(i, j));
}