So, it's possible to declalre anonymous class or struct but how to I make it useful?
int main() {
class{
int ClassVal;
};
struct{
short StructVal;
};
StructVal = 5; //StructVal is undefined
ClassVal = 5; //ClassVal is undefined too?
return 0;
}
if you put both of them outside of main function they will be inaccessible as well.
I'm asking this only because it's somehow intersting :)
EDIT:
Why union outside of main function (at global scope) must be static declared
for example:
static struct {
int x;
};
int main() {
//...
}
Anonymous classes and structures may be used to directly define a variable:
int main()
{
class
{
int ClassVal;
} classVar;
struct
{
short StructVal;
} structVar;
structVar.StructVal = 5;
classVar.ClassVal = 5;
return 0;
}
The above is not very common like that, but very common when used in unions as described by Simon Richter in his answer.
These are most useful in the form of nested struct and union:
struct typed_data {
enum type t;
union {
int i; // simple value
struct {
union { // any of these need a length as well
char *cp;
unsigned char *ucp;
wchar_t *wcp;
};
unsigned int len;
};
};
};
Now typed_data is declared as a type with the members t, i, cp, ucp, wcp and len, with minimal storage requirements for its intended use.
Related
How to initialize two or more structures with the same data? This has to be done at compile time to be as default data for const structures that are non-member global variables.
EDIT:
And what about C?
Works for me:
// header
struct Foo {
int a;
int b;
};
extern Foo const x;
extern Foo const y;
// cpp file
Foo const x{2, 3};
Foo const y = x;
Edit: reinterpreted the question a little.
One way is:
#define DATA { bla,bla,bla,bla }
var a = DATA;
var b = DATA;
You can use the copy constructor to initialize the structs. (This requires the use of a helper function to ensure correct order of initialization.) If the structures are POD, this should be as efficient as regular compile-time initialization:
struct A {
int a;
double c;
};
A initial_data() {
return { 1, 2.0 };
}
A a = initial_data();
A b = initial_data();
How can we access a structure's member without knowing the name of it?
For example : This is my struct.
struct A
{
int a;
char b;
int c;
}
Now I want to access char member of the struct A without using it's name.
I have only a pointer to that structure.
Example : struct A *temp;
Now I need to access with 'temp'.
I know the question is simillar to this How would you access a C structure's members without knowing the name?,
but it doesn't clarified my doubt.
From the comments, I understand you have the following function
struct A;
void foo( struct A * temp )
{
// access temp->b here
}
If you can include the file that has struct A's definition, do so
#include "A.h"
void foo( struct A * temp )
{
do_something_with_b(temp->b);
}
If you can't include the file, do what Luc Forget suggested in his answer:
Declare a struct B with identical structure, and cast temp to struct B. Because struct B have the same memory layout as struct A, accessing ((struct B*)temp)->e is identical to accessing A->b.
If you what are the structure fields, I think the simplest way of accessing the fields is to declare another structure Struct B with the same fields and casting your struct A* to struct B and then accessing the fields in a "traditional" way.
Here is a simple example of what I mean :
#include <stdlib.h>
#include <stdio.h>
struct A {
int a;
char b;
int c;
};
struct B {
int d;
char e;
int f;
};
void printStruct(void* struct_ptr)
{
struct B *tmp = struct_ptr;
fprintf(stdout, "a:%d b:%c c:%d\n", tmp->d, tmp->e, tmp->f);
}
int main(int argc, char** argv)
{
struct A test = { 42, 'A', 24 };
printStruct(&test);
}
Here printStruct "doesn't know" the field names of Struct A but can access them
If You know the types and order of members (as well as packing) then You can create another struct and cast a pointer, like so:
struct AMirror {
int a;
char b;
int c;
};
void function_to_use_struct(AMirror *ptr);
...
A *s;
...
function_to_use_struct((AMirror*)s);
The below code should work
void *b=temp;
int *c = (int *) b;
cout<<"Value1: "<<*c <<endl;
char *cc =(char *) (b+4);
cout<<"Char1: "<<*cc<<endl;
c =(int *) (b+6);
cout<<"Value2: "<<*c<<endl;
I guess one way is to cast and increment the char* , but in this case you must know the types and order of declarations of your members.
I want to use a nested structure, but I don't know how to enter data in it. For example:
struct A {
int data;
struct B;
};
struct B {
int number;
};
So in main() when I come to use it:
int main() {
A stage;
stage.B.number;
}
Is that right? If not how do I use it?
Each member variable of a struct generally has a name and a type. In your code, the first member of A has type int and name data. The second member only has a type. You need to give it a name. Let's say b:
struct A {
int data;
B b;
};
To do that, the compiler needs to already know what B is, so declare that struct before you declare A.
To access a nested member, refer to each member along the path by name, separated by .:
A stage;
stage.b.number = 5;
struct A {
struct B {
int number;
};
B b;
int data;
};
int main() {
A a;
a.b.number;
a.data;
}
struct B { // <-- declare before
int number;
};
struct A {
int data;
B b; // <--- declare data member of `B`
};
Now you can use it as,
stage.b.number;
The struct B within A must have a name of some sort so you can reference it:
struct B {
int number;
};
struct A {
int data;
struct B myB;
};
:
struct A myA;
myA.myB.number = 42;
struct A
{
int data;
struct B
{
int number;
}b;
};
int main()
{
A stage = { 42, {100} };
assert(stage.data == 42);
assert(stage.b.number == 100);
}
struct TestStruct {
short Var1;
float Var2;
char Var3;
struct TestStruct2 {
char myType;
CString myTitle;
TestStruct2(char b1,CString b2):myType(b1), myTitle(b2){}
};
std::vector<TestStruct2> testStruct2;
TestStruct(short a1,float a2,char a3): Var1(a1), Var2(a2), Var3(a3) {
testStruct2.push_back(TestStruct2(0,"Test Title"));
testStruct2.push_back(TestStruct2(4,"Test2 Title"));
}
};
std::vector<TestStruct> testStruct;
//push smthng to vec later and call
testStruct.push_back(TestStruct(10,55.5,100));
TRACE("myTest:%s\n",testStruct[0].testStruct2[1].myTitle);
I have somewhat like the following code running for a while live now and it works.
// define a timer
struct lightTimer {
unsigned long time; // time in seconds since midnight so range is 0-86400
byte percentage; // in percentage so range is 0-100
};
// define a list of timers
struct lightTable {
lightTimer timer[50];
int otherVar;
};
// and make 5 instances
struct lightTable channel[5]; //all channels are now memory allocated
#zx485: EDIT: Edited/cleaned the code. Excuse for the raw dump.
Explanation:
Define a lightTimer. Basically a struct that contains 2 vars.
struct lightTimer {
Define a lightTable. First element is a lightTimer.
struct lightTable {
Make an actual (named) instance:
struct lightTable channel[5];
We now have 5 channels with 50 timers.
Access like:
channel[5].timer[10].time = 86400;
channel[5].timer[10].percentage = 50;
channel[2].otherVar = 50000;
I'm not sure what I'm doing...
Let say I have a structure
struct Inner{
exampleType a;
int b;
}
struct Outer{
int current;
int total;
Inner records[MAXNUMBER];
}
struct Outer2{
Outer outer;
}
And I have the following functions:
void try3( Outer2& outer, type var, type2 var2 ){
}
void try2( Outer2* outer ){
try3(*outer, var, var2);
}
Inside main:
int myMain( int argc, char *argv[] ){
Outer2 outer2;
try2 (&outer2);
}
Here's the question. Can I increment the value of current by sticking the following line in try3:
++outer.outer.current;
errr, no, try3 has no knowledge of a thing caller outer2.
you can go outer.outer.current++; in try3
Sure you can, why not? Here is a working example for you:
typedef short exampleType;
struct Inner
{
exampleType a;
int b;
};
struct Outer
{
enum { MAXNUMBER = 2 };
int current;
int total;
Inner records[MAXNUMBER];
};
struct Outer2
{
Outer outer;
};
typedef int type;
typedef int type2;
void try3 (Outer2& outer, type var, type2 var2)
{
++outer.outer.current;
}
void try2 (Outer2* outer)
{
int var = 1, var2 = 2;
++outer->outer.current;
try3(*outer, var, var2);
}
int main ()
{
Outer2 outer2;
outer2.outer.current = 1986;
try2 (&outer2);
}
From try3, you would need to use ++outer.outer.current since outer is the name of the variable at the point. To answer the actual question though, look at the two functions. try2 takes a pointer to an Outer2, so no copy is made. try2 passes this to try3 which take a reference to an Outer2, so again no copy is made. This means that yes, ++outer.outer.current will in fact affect the original outer2 declared in myMain.
Edit (per Brian's comment)
However, outer.outer.current is never initialized, unless that's not your true myMain, so the final value of current is undefined since the value was never defined before the increment.
I have the following class in C++:
class a {
const int b[2];
// other stuff follows
// and here's the constructor
a(void);
}
The question is, how do I initialize b in the initialization list, given that I can't initialize it inside the body of the function of the constructor, because b is const?
This doesn't work:
a::a(void) :
b([2,3])
{
// other initialization stuff
}
Edit: The case in point is when I can have different values for b for different instances, but the values are known to be constant for the lifetime of the instance.
With C++11 the answer to this question has now changed and you can in fact do:
struct a {
const int b[2];
// other bits follow
// and here's the constructor
a();
};
a::a() :
b{2,3}
{
// other constructor work
}
int main() {
a a;
}
Like the others said, ISO C++ doesn't support that. But you can workaround it. Just use std::vector instead.
int* a = new int[N];
// fill a
class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};
It is not possible in the current standard. I believe you'll be able to do this in C++0x using initializer lists (see A Brief Look at C++0x, by Bjarne Stroustrup, for more information about initializer lists and other nice C++0x features).
std::vector uses the heap. Geez, what a waste that would be just for the sake of a const sanity-check. The point of std::vector is dynamic growth at run-time, not any old syntax checking that should be done at compile-time. If you're not going to grow then create a class to wrap a normal array.
#include <stdio.h>
template <class Type, size_t MaxLength>
class ConstFixedSizeArrayFiller {
private:
size_t length;
public:
ConstFixedSizeArrayFiller() : length(0) {
}
virtual ~ConstFixedSizeArrayFiller() {
}
virtual void Fill(Type *array) = 0;
protected:
void add_element(Type *array, const Type & element)
{
if(length >= MaxLength) {
// todo: throw more appropriate out-of-bounds exception
throw 0;
}
array[length] = element;
length++;
}
};
template <class Type, size_t Length>
class ConstFixedSizeArray {
private:
Type array[Length];
public:
explicit ConstFixedSizeArray(
ConstFixedSizeArrayFiller<Type, Length> & filler
) {
filler.Fill(array);
}
const Type *Array() const {
return array;
}
size_t ArrayLength() const {
return Length;
}
};
class a {
private:
class b_filler : public ConstFixedSizeArrayFiller<int, 2> {
public:
virtual ~b_filler() {
}
virtual void Fill(int *array) {
add_element(array, 87);
add_element(array, 96);
}
};
const ConstFixedSizeArray<int, 2> b;
public:
a(void) : b(b_filler()) {
}
void print_items() {
size_t i;
for(i = 0; i < b.ArrayLength(); i++)
{
printf("%d\n", b.Array()[i]);
}
}
};
int main()
{
a x;
x.print_items();
return 0;
}
ConstFixedSizeArrayFiller and ConstFixedSizeArray are reusable.
The first allows run-time bounds checking while initializing the array (same as a vector might), which can later become const after this initialization.
The second allows the array to be allocated inside another object, which could be on the heap or simply the stack if that's where the object is. There's no waste of time allocating from the heap. It also performs compile-time const checking on the array.
b_filler is a tiny private class to provide the initialization values. The size of the array is checked at compile-time with the template arguments, so there's no chance of going out of bounds.
I'm sure there are more exotic ways to modify this. This is an initial stab. I think you can pretty much make up for any of the compiler's shortcoming with classes.
ISO standard C++ doesn't let you do this. If it did, the syntax would probably be:
a::a(void) :
b({2,3})
{
// other initialization stuff
}
Or something along those lines. From your question it actually sounds like what you want is a constant class (aka static) member that is the array. C++ does let you do this. Like so:
#include <iostream>
class A
{
public:
A();
static const int a[2];
};
const int A::a[2] = {0, 1};
A::A()
{
}
int main (int argc, char * const argv[])
{
std::cout << "A::a => " << A::a[0] << ", " << A::a[1] << "\n";
return 0;
}
The output being:
A::a => 0, 1
Now of course since this is a static class member it is the same for every instance of class A. If that is not what you want, ie you want each instance of A to have different element values in the array a then you're making the mistake of trying to make the array const to begin with. You should just be doing this:
#include <iostream>
class A
{
public:
A();
int a[2];
};
A::A()
{
a[0] = 9; // or some calculation
a[1] = 10; // or some calculation
}
int main (int argc, char * const argv[])
{
A v;
std::cout << "v.a => " << v.a[0] << ", " << v.a[1] << "\n";
return 0;
}
Where I've a constant array, it's always been done as static. If you can accept that, this code should compile and run.
#include <stdio.h>
#include <stdlib.h>
class a {
static const int b[2];
public:
a(void) {
for(int i = 0; i < 2; i++) {
printf("b[%d] = [%d]\n", i, b[i]);
}
}
};
const int a::b[2] = { 4, 2 };
int main(int argc, char **argv)
{
a foo;
return 0;
}
You can't do that from the initialization list,
Have a look at this:
http://www.cprogramming.com/tutorial/initialization-lists-c++.html
:)
A solution without using the heap with std::vector is to use boost::array, though you can't initialize array members directly in the constructor.
#include <boost/array.hpp>
const boost::array<int, 2> aa={ { 2, 3} };
class A {
const boost::array<int, 2> b;
A():b(aa){};
};
How about emulating a const array via an accessor function? It's non-static (as you requested), and it doesn't require stl or any other library:
class a {
int privateB[2];
public:
a(int b0,b1) { privateB[0]=b0; privateB[1]=b1; }
int b(const int idx) { return privateB[idx]; }
}
Because a::privateB is private, it is effectively constant outside a::, and you can access it similar to an array, e.g.
a aobj(2,3); // initialize "constant array" b[]
n = aobj.b(1); // read b[1] (write impossible from here)
If you are willing to use a pair of classes, you could additionally protect privateB from member functions. This could be done by inheriting a; but I think I prefer John Harrison's comp.lang.c++ post using a const class.
interestingly, in C# you have the keyword const that translates to C++'s static const, as opposed to readonly which can be only set at constructors and initializations, even by non-constants, ex:
readonly DateTime a = DateTime.Now;
I agree, if you have a const pre-defined array you might as well make it static.
At that point you can use this interesting syntax:
//in header file
class a{
static const int SIZE;
static const char array[][10];
};
//in cpp file:
const int a::SIZE = 5;
const char array[SIZE][10] = {"hello", "cruel","world","goodbye", "!"};
however, I did not find a way around the constant '10'. The reason is clear though, it needs it to know how to perform accessing to the array. A possible alternative is to use #define, but I dislike that method and I #undef at the end of the header, with a comment to edit there at CPP as well in case if a change.