I have an array I want it to be a private member variable. The way my program works as implementing selection sort is, main method feeds in the size of the array, and the constructor passes in and creates the new array with given size.
I've done with in Java, but can't figure out in C++.
(After taking a look at other people's post on this web, I figured out I have to make my variable static)
Thank you.
[ArrayS.h]
public:
ArrayS(void);
ArrayS(int max);
~ArrayS(void);
private:
static long a [0];
[ArrayS.cpp]
ArrayS::ArrayS(void)
{
}
ArrayS::ArrayS(int max)
{
long ArrayS::a [max];
nElems = 0;
}
Thank you.
There are two issues with the code above. The first is that in C++ you cannot have an array of size 0. The second one is that for static members of a class, you need to provide a definition in exactly one translation unit:
struct test {
static long a[10];
};
// in a single .cpp
long test::a[10] = {};
Other than that, if you need arrays of a size that is only known at runtime, you cannot use raw arrays. You could use dynamically allocated memory (through new[]) but you are better off using std::vector<long>. Additionally, it is unclear whether you really need the member to be static at all. The static keyword in that context means class member (that is, shared by all code in the program, not per-instance data)
You need to define the variable again, outside the class. whenever you have a static member.
Although g++ compiles c++ code which has arrays of size zero, reconsider if that's what you really want.
Related
Instead of making a new question I will edit this one by completely erasing the previous one, hopefully making it less confusing.
Wall of text.
I have a basic struct that has some basic values, such as image width, height and x and y positions, like so:
struct obj {
int id = 0;
float x = 0;
float y = 0;
int image_w = 0;
int image_h = 0;
int depth = 0;
}
I then have an initialiser function that creates the members of that struct and stores them in an array. If that array is named "instance" then individual members and their values can be accessed by simply doing this: instance[number].x etc..
Then I have a loop or two which handle all these members and do so in the order of their depth value, defined in struct and set in initialiser function. Like so (simplified):
for (i=0;i<maxdepth;i++) {
if (instance[n].depth == i) { doStuff; }
}
In "doStuff" function I check the members' id value in a switch statement and then have them do whatever I want inside case labels; this gives me the option to have some individual behavior within the same struct. And here is where the problem is. Although this works just fine I can't have individual fixed (or starting) variables within certain members without every member having those same variables and obviously with enough members this eventually results in a struct that is simply undesirably big and has a lot of redundancy; wasted resources. E.g I want some members to have speed and direction variables but don't want to give them to static members of the same struct that don't need them.
The question is, how do I achieve this effect without changing the fundamental idea of using structs or is there a better alternative to do this?
And I'm sorry about formatting and all; this is my first question on this website.
My understanding of structs is that the bigger it is the more time it takes to access its individual variables.
Your understanding is fundamentally mistaken. The size of a struct has little (if any) effect on the time required to access an individual variable inside that struct.
Regardless of that, however, your basic idea of structuring the data so one struct contains (or owns a pointer to) some other structs is perfectly fine and reasonable.
What's not so fine or reasonable is making that pointer essentially un-typed so it can refer to any other type. If you want a collection of clothes, you'd probably start with a clothing base class, and then derive various other types from that (coat, shirt, slacks, jeans, etc.). Then the person type might contain (for example) a vector of pointers to clothing, so it can contain pointers to all the other types derived from clothing.
As far as "extending scope" goes...well, I can't say much beyond the fact that I can't make much sense of what you're trying to say there.
I have a question regarding good design in C++. I have a class A, and all objects of this class use an integer array of constant values (they should share the same array, as their values are constant). The array needs to be computed (just once) before any object A.
I thought about having another class B which contains the integer array as a static member, an init() method which would fill this array according to some formula and a static boolean flag initialized (if this variable if true then the init() method would do nothing), but I'm not sure this is the best way to solve my design issue.
So my question is, what would be a good design/way to accomplish this ?
Thanks in advance.
Since the array is constant, use const.
Since the array is shared among all instances of the class, use static.
In your header file, declare it:
class A
{
static const int the_array[10];
}
In A's source file, initialize the one instance:
const int A::the_array[10] = { ... };
Edit from comment...
Or, if the array is better generated algorithmically, use a constant pointer. The usage syntax for the array would be the same.
Note that both the array and the pointer are const.
Header:
class A
{
static const int * const the_array;
}
Source file:
namespace
{
const int * generate_my_array()
{
// Allocate an array, initialize it, return it.
}
}
const int * const A::the_array = generate_my_array();
I've come across a bit of code which essentially looks like this:
#include<iostream>
// in a header file
class xxx{
public:
xxx() { xxx_[0]=0; xxx_[1]=0; xxx_[2]=0;}
double x0() const {return xxx_[0];}
private:
double xxx_[3]; // ???
};
// in the main.cpp
int main(){
xxx x;
std::cout<<x.x0()<<"\n";
}
The question is --- is declaring as a class member an array of fixed size is really allowed by the standard?
There is nothing wrong with the above code. It might not be the best way to write it, but there is nothing intrinsically wrong with it.
Yes, your class xxx may contain a fixed-size array as a member. It's allowed in C too.
The compiler, even when reading the header to use it, knows how big to make sizeof(xxx) as a result.
There is nothing wrong with declaring static array as a member of class:
class A
{
int a[3];
};
It is allowed.
Design-wise, this is often not ideal, though; arrays don't have such a nice interface as std::array has:
std::array<double,3> xxx_;
for (auto it : xxx_) {...}
xxx_.size()
std::transform (xxx_.begin(), xxx_.end(), ...);
etc. So if you find yourself using your (static sized) array as a container most of the time, you should replace it with std::array (which has no spatial overhead). If you need dynamic sized arrays, look at std::vector, which has a small overhead (size + capacity, however, with manual allocation, you must remember the size, too, so the only overhead is capacity).
I am trying to do a simple class to unique ID conversion. I am thinking about adding a static method:
class A {
static int const *GetId() {
static int const id;
return &id;
}
};
Each class would then be identified by unique int const *. Is this guaranteed to work? Will the returned pointer really be unique? Is there any better simpler solution?
I have also thought about pointer to std::type_info:
class A {
static std::type_info const *GetId() {
return &typeid(A);
}
};
Is that better?
Edit:
I don't need to use the id for serialization. I only want to identify a small set of base classes and I want all subclasses of some class to have the same id
Yes, this will work. Each static local will be given distinct memory location at the time when the module is loaded and it will persist until the module is unloaded. Remember, static locals are stored in static storage that is distributed during compilation and they persist till the module gets unloaded, so they will have distinct memory locations.
The address of static variable is guaranteed to be unique and the same in all translation units.
It is not a good idea because it requires you to add code to every class to be identified.
The pointers to type info objects are not guaranteed to be unique, but the type info objects themselves are guaranteed to compare as equal for a given class, and as unequal for distinct classes. This means you can use small wrapper objects that carry type info pointers, and the delegate the comparisions to the type info objects. C++11 has such a wrapper in the standard library, and if you don't have access to that, there is one in Andrei Alexandrescu's "Modern C++ Design", and therefore probably also in the Loki library, there is probably one in Boost, and there is one on my Wordpress blog – it's not like you to have invent one from scratch.
If, however, the id's are to be used for serialization, then you need id's that are valid across builds. And in that case you you need strings or UUIDs. I would go with UUIDs.
To associate a class with an UUID you can in general use a type traits class. Or if you're only doing Windows programming then you can use Visual C++'s language extensions for this. I think but I am not 100% sure that those language extensions are also implemented by g++ (in Windows).
Cheers & hth.
As I have noticed at least MSVC 2008 or 2010 optimizes the static variable, so that the following GetId function returns same address even for different classes.
static int const *GetId() {
static const int i = 0;
return &i;
}
Therefore address of uninitialized constant static variable may not be used for identification. The simplest fix is to just remove const:
static int *GetId() {
static int i;
return &i;
}
Another solution to generate IDs, that seems to work, is to use a global function as a counter:
int Counter() {
static int i = 0;
return i++;
}
And then define the following method in the classes to be identified:
static int GetId() {
static const int i = Counter();
return i;
}
As the method to be defined is always the same, it may be put to a base class:
template<typename Derived>
struct Identified {
static int GetId() {
static const int i = Counter();
return i;
}
};
And then use a curiously recurring pattern:
class A: public Identified<A> {
// ...
};
The address of the static int is guaranteed to be unique for each
function (and the same for every call to the same function). As such,
it can work very well as an id within a single execution of the code.
The address could conceivably change from one run to the next, and will
often change from one compilation to the next (if you've changed
anything in the code), so it is not a good solution for an external id.
(You don't say whether the id must be valid outside a single execution
or not.)
The address of the results of a typeid is not guaranteed to be the
same each time you call the function (although it probably will be).
You could use it to initialize a pointer, however:
static std::type_info const& GetId()
{
static std::type_info const* id = &typeid(A);
return id;
}
Compared to using int*, this has the advantage of providing additional
information (e.g. for debugging). Like int*, the identifier may be
different from one run to the next; A::GetId()->name() will point to
the same '\0' terminated string (although again the address might be
different) provided you compile with the same compiler. (As far as I
can tell, the standard doesn't guarantee this, but in practice, I think
you're safe.) Change compilers, however, and all bets are off.
The solution I've used in the past is something like:
static char const* GetId()
{
return "A"; // Or whatever the name of the class is.
}
This provides a unique identifier, easily compared, within a single
execution of the code, and a string value which can be used as an
external identifier, and which is guaranteed across all compilers. We
implemented this as a macro, which defined both the static function, and
a virtual function which returned it, e.g.:
#define DECLARE_IDENTIFIER(name) \
static char const* classId() { return STRINGIZE(name); } \
virtual char const* id() { return classId(); }
This results in a very fast (but limited) RTTI, and supports external
identifiers for serialization and persistency.
The int* method would be unique, since a different static memory cell must be allocated for each static variable, and I'd guess it is simpler to understandthan the type_info idea.
Clearly pointers to different variables must have different values. Just watch out if you choose to derive a subclass of A. You need to decide what your policy is for id. If you did nothing then the subclass would have the same id.
In general, you really really want to avoid hacky things like this. If I really had to do this, I'd look at using some UUID system (there's a library in Boost for that, but I'm not very familiar with it), or some singleton that maintained a list of these objects for whatever purpose you need.
Static variables are initialized before Heap & Stack memory so yeah it will be unique.
Quirky though.
Because you will have to add this method to all classes that require a UID you may as well do this.
unsigned int getUID()
{
return 12;
}
The advantage of this is that the compiler will be able to use a jump table if you are using this for RTTI for switching on type, which will not be possible with two pointers because the jump table would be very sparse.
The (minor) disadvantage is you need to keep track of which identifiers have been taken.
A major disadvantage of the first method you presented is that the same numbers cannot be used to identify objects because the virtual getUID() method won't be able to take the address of the variable in another function's scope.
I have following two classes:
template <size_t size>
class Cont{
public:
char charArray[size];
};
template <size_t size>
class ArrayToUse{
public:
Cont<size> container;
inline ArrayToUse(const Cont<size+1> & input):container(reinterpret_cast<const Cont<size> &>(input)){}
};
I have three following lines of code at global scope:
const Cont<12> container={"hello world"};
ArrayToUse<11> temp(container);
char (&charArray)[11]=temp.container.charArray;
In totality of my code The only usage of "container" object is for initialization of an object of "ArrayToUse" class as mentioned and after initialization of "charArray" reference to "temp.container.charArray" I'll use that reference in rest of my code, now I'm wondering does compiler reserve memory for "container" object since that's got a temporary usage?
Any variable defined at global scope has memory reserved for it at compile time. That does not mean it's guaranteed to be properly initialized, but it's there all the same.
At link-time, Visual C++ offers the option to strip unused data and functions via /OPT - see here.
it totaly depends on your particular compiler so i'd say inspect the assembly and find out!
the compiler could optimize container out, or it could neglect to do so.
The compiler should create the container variable in the compiled object file. The linker is the one that can tell if it's needed or not (for an exported symbol, or from another compilation unit if declared extern).
But...
The type Cont<x> is unrelated to Cont<x+1>. You cannot depend on the memory of a member variable being layed out in similar fashions. Heck, you cannot even know if it looks the same, since there is this thing called 'template specialization':
// your code
template <size_t size>
class Cont{
public:
char charArray[size];
};
// my evil tweak
// I'm the worst compiler ever but I feel that this
// array would better be represented as a map...
template<> class Cont<12> {
std::map<int,char> charArray;
};
// your screwed up result
Cont<12> c12;
Cont<11>& c11( reinterpret_cast<Cont<11>&>(c12) );
char (&s11)[11] = c11.charArray; // points to the first byte of a list object...
EDIT -- #UncleBen's comment insinuates I'm overdoing here. And he's right.
according to wikipedia,
A pointer to a POD-struct
object, suitably converted using a
reinterpret cast, points to its
initial member and vice versa,
implying that there is no padding at
the beginning of a POD-struct.
So in this case,
where the charArray is the first member of a Cont<n>, and there are no non-POD members
there is no assignment operator, nor a destructor
It is safe.