hello every i have made a structure and i want to make 2 objects of it . i am using qtcreator.
i write
struct grapharray gao ; (grapharray is my structure)
every thig works well but when i write another object like
struct grapharray gao ;
struct grapharray gao1 ;
my program unexpectedly finishes can any one tell me why is it so and where should i declare the struct object
struct grapharray
{
int structcol;
double *structpayloadgraph;
double *structsessiongraph;
};
here is my structure;
and i have a function
struct grapharray graphplotdata(char * filename)
{ // computing some values and returning structure object
}
thanks
If I understand well the problem, I would say that you use far too much the "struct" keyword.
If you define your struct as
struct grapharray
{
int structcol;
double *structpayloadgraph;
double *structsessiongraph;
};
then you don't need to use the keyword "struct" when declaring the variables.
grapharray gao; // without struct keyword
grapharray gao1; // without struct keyword
and your function should be
grapharray graphplotdata(char * filename) // without struct once again.
{
// computing some values and returning structure object
}
structs does works almost the same way as classes; the main difference is that structs members and methods are "public" by default and classes members and methods are "private" by default.
Edit: Considering the comment of Dennis Zickefoose, this is not the good answer.
Related
So I'm trying to nest a struct into another one by value, but I want to be able to import the members of the nested structs as if they are direct members of Generic struct. There seems to be a using keywork in C++, but it doesn't work as I would have expected.
For example:
struct A
{
int a;
// some specific A stuff
};
struct B
{
float a;
// some specific B stuff
};
template<typename T>
struct Generic
{
Kind kind; // an enum or an integer ID that allow to figure out what type is contained
// some generic stuff
// how to do this?
using T t; // Error: a class-qualified name is required
// some more generic stuff
};
void foo()
{
Generic<B> g;
g.t.a = 6.7 // we can do this with regular struct field
g.a = 5.4; // but need to be able to do this
}
This construct is made in this way to be able to create different user-extensible views into some differently-sized item buffer, where each item is a tagged union with custom contents and common header and footer.
So the main question: How to import ("use") some struct into a different one and be able to access the nested struct' fields directly?
There is a possible way to work around the problem by using inheritance, but it needs more structures:
// The "data" structures
struct A { ... };
struct B { ... };
// Common "header" structure
struct Header { ... };
// The "generic" structure to combine the header with the data
template<typename D>
struct Data : Header, D
{
// Empty
};
Now you can use the B data as
Data<B> data;
The header information will come first, the actual data follow. And the size will depend on the data structure.
But please note that from a design point of view, this is highly dubious. I would prefer actual composition:
struct A
{
// Actual A data fields follow
};
struct Data_A
{
Header header;
A data;
};
This allows you to read the header and data separately from the buffer. It's also more explicit about the separation of the header and the data, and should make the code clearer and easier to read, understand and maintain.
I have this code right now, which seems to work so far but I was wondering if there was a way to get the exact same struct in a more elegant way since my method so far needs a duplicate everytime for each struct... The end goal would be to have a typedefed struct which would swap the bytes according to the endianness automatically.
using ResourceHeader_t = struct ResourceHeader_s
{
uint32_t magic;
uint32_t chunkVersion;
uint32_t chunkSize;
};
template<bool bigEndian>
struct ResourceHeader : public ResourceHeader_s
{
ResourceHeader(ResourceHeader_t* ptr) : ResourceHeader_s(*ptr)
{
if (bigEndian)
{
LITTLE_BIG_SWAP(magic);
LITTLE_BIG_SWAP(chunkVersion);
LITTLE_BIG_SWAP(chunkSize);
}
}
};
Usage example :
ResourceHeader<true> resourceHeader((ResourceHeader_t *)fileBuffer);
There is no need for a typedef struct declaration in C++. This is a relic of C.
In C++, after declaring a struct ResourceHeader_s, or struct ResourceHeader_t, or just a plain struct ResourceHeader, the same symbol can be used directly by itself, without an explicit struct.
You might simply add the endianess as a ResourceHeader ctor parameter, rather than a template parameter. This would remove duplicate definitions of the struct (one for big and one not).
Consider following code.
In my real case scenario i have somthing like that:
typedef enum
{
vehicle,
computer,
} Article;
And that is what I'm trying to construct:
enum class status{
notPaid,
paid,
};
struct S {
status status_vehicle;
status status_computer;
std::map<Article, status> mymap =
{
{vehicle, S::status_vehicle},
{computer, S::status_computer},
};
};
int main ()
{
Article a1 = vehicle;
S::mymap.at(a1) = status::paid; // this line doesn't work
}
However, the last line (S::mymap.at(a1) = status::paid;) is not working. I've tried different approaches, using the find() function of std::map for example. I got the error "assignment of member std::pair<Article, status>::second in read only object".
Does someone know, how to do that? Also maybe how to design the whole in a better way? (the whole from the line "And that is what I'm trying to construct").
Also I would have prefer to use an unordered_map instead of a map but was not working. Thanks
Because mymap is not static.
You can do like this:
Article a1 = vehicle;
struct S mystruct;
mystruct.mymap.at(a1) = status::paid;
Or add static to your member in struct:
struct S {
status status_vehicle;
status status_computer;
static std::map<Article, status> mymap;
};
But when using static, you have to initialize mymap outside declaration of struct S and member that you can't use non-static members of struct
std::map<Article,status> S::mymap={
{vehicle,S::status_vehicle}
};
A static member is shared by all objects of the class. All static data
is initialized to zero when the first object is created, if no other
initialization is present
And logically is not good in your example
https://en.cppreference.com/w/cpp/language/static
Since myMap is non-static, it cannot be assigned as static variables are.
You can change your code like this:
int main ()
{
Article a1 = vehicle;
S ss;
ss.mymap.at(a1) = status::paid;
}
Generally, in order to initialize a struct in c, we could only specify part of the fields. Like below:
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
However, in C++, we should initialize the variables in the struct without naming the fields.
Now, what if I would like to initialize a struct using the c style while using the g++ compiler, how to accomplish this? PS: the reason I need to do this is that the struct fuse_operations has too many fields in it.
You wrote:
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
Generally, in order to initialize a struct in c, we could only specify part of the fields [...] However, in C++,
we should initialize the variables in the struct without naming the fields. Now, what if I would like to initialize
a struct using the c style while using the g++ compiler, how to accomplish this? PS: the reason I need to do this
is that the struct fuse_operations has too many fields in it.
My solution was to specialize the struct with a constructor:
struct hello_fuse_operations:fuse_operations
{
hello_fuse_operations ()
{
getattr = hello_getattr;
readdir = hello_readdir;
open = hello_open;
read = hello_read;
}
}
Then declare a static instance of the new struct:
static struct hello_fuse_operations hello_oper;
Testing worked OK for me (but this depends on the memory layout of the C-struct and C++-struct to be the same -- not sure that's guaranteed)
* UPDATE *
Though this approach worked fine in practice, I have subsequently converted my code to use a utility class, i.e., a class with a single static 'initialize' method that takes a reference to a fuse_operation struct and initializes it. This avoids any possible uncertainty regarding memory layout, and would be my recommended approach in general.
Unfortunately, even the C++11 version of the C++ standard lacks the designated initializers feature of C99.
maybe you can write a variable param function which takes as input the function pointers and assigns the rest of the attribs as NULL. Since you only have one struct - fuse_operations, you can implement the function for only one struct. something like init_struct(int no_op, ...) wherein you pass function pointers to implementations. Its too complex and laborious, but I suppose you can write it once and use it always...
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).