enum initialization issue - c++

Here is a sample program :
class BASE
{
public:
enum ABC
{
ZERO,
ONE,
TWO,
LAST
};
BASE(ABC exp): type(exp)
{
A[ZERO] = "1111";
A[ONE] = "22222";
A[LAST] = "LLLL";
}
virtual const char* what()throw()
{
return A[type];
}
private:
const char* A[LAST];
const ABC type;
};
int main()
{
BASE a(BASE::ONE);
cout<<a.what()<<"\n";
return 0;
}
The above program terminates with segmentation fault, as 'type' enum variable is not initialized with specified value but with some random default ?

A is an array of three pointers, A[0], A[1], and A[2].
You have a pointer to "LLLL" which is OK. But when you try to assign that pointer to A[3], there is no such object as A[3].

You declare the array A as
const char* A[LAST];
This means that the indices 0 .. (LAST-1) are all valid. However, in the BASE constructor you perform
A[LAST] = "LLLL";
This is an out-of-bounds access to the array.

If you want a "LAST" entry, try this:
enum ABC
{
ZERO,
ONE,
TWO,
LAST = TWO
};

Related

How to store a reference to a C-style array in a class?

class Class
{
public:
Class(array[3][3]) //the constructor
{
this->array = array
}
array[3][3];
};
int main()
{
array[3][3] = {...initialization...};
Class object(array[3][3]);
}
I want to make an object, which uses the 2d array and modifies it. I know that C arrays are just pointers to an address, but I couldn't pass it in the constructor no matter how many *, & or [] I write.
The most clever thing I could think of is making an array of POINTERS in the class, and assigning each pointer, to the address of the original array's element via for loop, but then every time I want to modify, or read from the array in main, I have to write for example *array[2][1] = 3.
Any clever solution?
If I finally got the question correctly, you can use a reference to an array:
struct Class {
Class(int (&array)[3][3]) : array_(array)
{}
void set11(int value) {
array_[1][1] = value;
}
int (&array_)[3][3];
};
int main() {
int array[3][3]{};
Class object(array);
object.set11(99);
std::cout << array[1][1]; // Prints 99
}
If that's not what you want, please clarify your question.
Here's how to declare a pointer in your class that can point to the array in main.
class Class
{
public:
Class(int (*array)[3])
{
this->array = array;
}
int (*array)[3];
};
int main()
{
int array[3][3] = { ... };
Class object(array);
}

Assigning array value by reference without memcpy()?

Lets say i have an array that holds structs called computer; Whenever I try to assign an element to the array it uses the "memcpy()" function, however i do not have access to this function or any other libraries. How do I assign an element to this array by reference without using memcpy()?
This would be my code if I had access to memcpy()
struct Computer{
int val;
};
int main(){
int i = 0;
Computer list[10];
Computer *p;
p->val = 5;
list[i] = *p;
}
Below is an array of Computer by value or by address if you prefer. Having an array of Computer* const is essentially the same as references because they cannot be reassigned:
struct Computer {
int val;
Computer() = delete;
Computer(int a) : val(a) {}
};
int main() {
Computer byValue[] = {
Computer(1),
Computer(2),
Computer(3)
};
Computer c1(1);
Computer c2(2);
Computer c3(3);
Computer* const byAddress[] = {
&c1,
&c2,
&c3
};
return 0;
}
Arrays of references are illegal in C++: Why are arrays of references illegal?

A Function that Returns 2 Arrays (Passing By Reference)

I have to do a function in c++ that returns 2 arrays by passing them from reference.
I have no idea and it seems noone also has.
Would you be so kind to write an exemple for me?
I thaught to do
int *vettore=new int[5];
return vettore
buy it only returns one.
Tnx in advance.
Let's forget about arrays for a second, because that is another bag of problems. Let's concentrate on returning two simple types, e.g. returning two integers.
Obviously this won't work (because... not python):
int, int foo()
{
int a = ...
int b = ...
return a, b;
}
So what options are you left with if you want to return multiple values in C++?
Option 1. Return a class
You can "bundle" your values in a class, either create a new class for them if that makes sense, or simply use std::pair or std::tuple:
std::pair<int, int> foo()
{
int a = ...;
int b = ...;
return {a, b}
}
Option 2. Use "out" parameters.
You can pass parameters by reference, thus being able to modify from within the function objects from outside. E.g.:
void foo(int& a, int& b)
{
a = ...;
b = ...;
}
I think this is what you teacher meant by "pass by reference".
Ok, what about arrays?
This is tricky to answer because it is not clear what you mean by arrays and some of the meanings are discouraged.
I will start from the most recommended, to what is considered bad practice and even wrong:
std::vector
The defacto type for representing arrays in C++ should always be std::vector. Thus your requirement of returning by reference could mean:
void foo(std::vector<int>& v1, std::vector<int&>& v2);
std::array
Alternately if the size of the array is known at compile time:
void foo(std::array<int, 24>& a1, std::array<int, 24>& a2);
C pointers
Ok, now we are in the discouraged territory. Don't do this, unless to appease an unreasonable teacher or curriculum:
void foo(int* &v1, int* &v2)
{
v1 = new int[11];
v2 = new int[24];
...
}
C arrays
void foo(int (&a)[11], int (&a2)[24]);
You could do this:
return std::make_pair(array1,array2);
You'll need to #include <utility>
To access the arrays use pair.first or pair.second
example:
#include <utility> //std::pair
#include <iostream> //std::cout
std::pair<int*,int*> returnpair(){
int arr1[3] = {1,2,3};
int arr2[3] = {4,5,6};
return std::make_pair(arr1,arr2);
}
int main(){
std::pair<int*,int*> pair= returnpair();
std::cout<<pair.first[1]; //access 2nd member of arr1
}
Output:
2
Reference:
http://www.cplusplus.com/reference/utility/pair/
You can do that by returning a struct node pointer which is acceptable in C/C++.
Following is the sample code of node :
struct node {
int a[100];
int b[100];
};
Coming to the function :
struct node* fun() {
struct node* ptr;
// write your code
return ptr;
}
In main : you can access the arrays as follows :
struct node* ptr=fun();
ptr->a // is the first array
ptr->b // is the second array
Hope it helps

What are values initialized to after calling Struct constructor?

I have a struct defined as:
typedef struct s non_t;
struct s {
char tName;
int rCount;
};
I then initialized it like this:
non_t *s = new non_t();
//s->tName = ???
//s->rCount = ???
So here, what do the values of s->tName and s->rCount get initialized to?? Are they null still? I want to copute something like:
s->rCount = s->rCount + 1
But in order for that to work properly I need s->rCount to be initialized to 0... I guess I'm just confused on how struct initialization really works?
As you add () in new non_t(), members would be value initialized, so member will have value 0 in your case.
With new non_t, the members would be default initialized, so uninitialized in your case.
Adding constructor would avoid those subtleties.
struct s {
s() : tName('\0'), rCount(0) {}
char tName;
int rCount;
};
or in c++11
struct s {
char tName = '\0';
int rCount = 0;
};
int and char cannot be null. The values will be undefined without a constructor that would initialize them.
struct s
{
s() : rCount(0) {}
char tName;
int rCount;
};
This would initialize rCount to zero.
If you need it to be initialized to 0, you should do it in a constructor. :)
Otherwise it'll be set to whatever random piece of memory it's allocated at.
struct s {
s() : tName(' '), rCount(0) {}
char tName;
int rCount;
};
In C++ struct works exactly like a class except all fields are public by default. You can make constructor that will initialize your struct with whatever default values you want.

C++ Array Member of Constant Length (Initialisation of)

I have a class that contains an array. I want this array to be set at the length of a constant:
// Entities.h
class Entities
{
private:
const int maxLimit;
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
The main problem I'm having is with the constructor. I thought:
// Entities.cpp
Entities::Entities() : maxLimit(50)
{
currentUsage = 0;
cout << "Entities constructed with max of 50" << endl;
}
would have been sufficient...but not so. I don't know if I can use the initialiser list for array initialisation.
How can I initialise the objects array using the maxLimit const? I'm relatively new to classes in C++ but I have experience with Java. I'm mainly testing out this phenomenon of 'constness'.
The array must have a constant length. I mean a length that is the same for all objects of that class. That is because the compiler has to know the size of each object, and it must be the same for all objects of that particular class. So, the following would do it:
class Entities
{
private:
static const int maxLimit = 50;
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
And in the cpp file:
const int Entities::maxLimit;
I prefer to use an enumeration for that, because i won't have to define the static in the cpp file then:
class Entities
{
private:
enum { maxLimit = 50 };
int objects[maxLimit];
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
If you want to have a per-object size of the array, then you can use a dynamic array. vector is such one:
class Entities
{
private:
const int maxLimit;
std::vector<int> objects;
int currentUsage;
public:
Entities();
bool addObject(int identifier);
void showStructure();
};
// Entities.cpp
Entities::Entities(int limit)
: maxLimit(limit), objects(limit), currentUsage(0)
{
cout << "Entities constructed with max of 50" << endl;
}
Best is to do as much initialization in the initialization list as possible.
You can use template argument if you need to set array size at compile time:
template<size_t maxLimit>
class Entities
{
int objects[maxLimit];
public:
Entities() {}
...
};
Entities<1000> inst;
to dynamically allocate the memory you may need to use the 'new' keyword like
objects would be defined like:
int * objects;
inside the constructor you would do:
objects = new int [maxLimit];
edit:
forgot to mention, you'll need to deallocate the array when you're done, probably in the destructor of the class.
delete[] objects;
const ints have to be initialized at declaration. If you don't know the value that it has to be at the time of declaration, you're going to have to adopt a different strategy.
You'll need to create the array in the constructor, while keeping a pointer outside. Is this what you want to do?
In your class :
private:
int maxLimit;
int* objects;
And outside:
Entities::Entities() : maxLimit(50)
{
currentUsage = 0;
cout << "Entities constructed with max of 50" << endl;
objects = new int[maxLimit];
}
Entities::~Entities()
{
delete [] objects;
}
If all objects have the same length, then length can be static. This makes it a constant integral expression allowed as an array bound:
class Entities
{
private:
static const int maxLimit = 50;
int objects[maxLimit];
int currentUsage;
//...
};
Remember that sizeof(Entities) is a valid expression. Each Entities object has that same size.
Use std::vector and you get the expected behaviour. No need to worry about pointers, copies, etc
#include <vector>
class Entities
{
private:
const int limit;
std::vector<int> objects;
public:
Entities(int a_limit)
: limit(a_limit), objects(a_limit)
{ }
void addObject(int identifier)
{
if (objects.size() == limit)
throw whatever;
objects.push_back(identifier);
}
};