I've got some very simple c++ code to show the problem. I initialize my array with values in the ctor. But when I try to access the array in main, those values are replaced with random numbers. Why?
//Example to figure out why initialization values are disappearing
#include <iostream>
struct Struct1
{
float array1[2];
//ctor
Struct1();
};
Struct1::Struct1()
{
float array1[] = {0.2,1.3};
}
int main()
{
Struct1 StructEx;
std::cout<<StructEx.array1[0]<<' ';
std::cout<<StructEx.array1[1]<<std::endl;
return 0;
}
As #crashmstr mentioned, you do not initialise the member of the structure, but a local variable. The following code should work:
struct Struct1
{
float array1[2];
//ctor
Struct1();
};
Struct1::Struct1()
: array1 ({0.2,1.3})
{
}
int main()
{
Struct1 StructEx;
std::cout<<StructEx.array1[0]<<' ';
std::cout<<StructEx.array1[1]<<std::endl;
return 0;
}
Switch on the warnings (-Wall) when compiling, and you will see
float array1[]={0.2,1.3}; is unused
StructEx.array1[0] and StructEx.array1[0] are uninitialized
In the constructor put this
array1[0]=0.2;
array1[1]=1.3;
Related
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);
}
I have a simple problem but I need to understand the concept behind it.
How to access data members of a 1st struct by instantiating it as pointer in 2nd struct.
If I make data members of 1st struct as pointer then how to print out there values by accessing them e.g.
struct temp
{
int a =5;
float b = 6.0;
i = &a;
f = &b;
int *i;
float *f;
};
I am working on a complex code so I need to understand the logic behind it as how it works in-terms of memory and logic.
Thanks a lot for your time in advance.
#include <iostream>
using namespace std;
struct temp {
int i=5;
float f=6.0;
};
struct qlt {
temp *d;
};
int sum (qlt *s)
{
int a = s->d->i;
// std::cout<<a;
}
int main() {
qlt x;
//int b = ;
std::cout <<sum(&x);
return 0;
}
qlt x;
This creates a qlt allright, but not the d inside it. So you have a dangling pointer (since it's also left uninitialized).
qlt x;
temp b;
x.d = &b;
this would be a C-style solution. C++ has way better ways to do it.
Forget all sort of pointers at this moment and use STL.
I come from Java and Ruby so I have a hard time coding simple stuff in c++, c++ being harder to tame...
I want to initialize an array in the class constructor with predefined values that can be accessed by all methods in the class. Yeah, basic stuff.
In other words, I want to do something like this:
Box.h
class SomeClass
{
public:
SomeClass(int something);
SomeMethod();
DoSomething(int thing);
protected:
int _something;
int[] arr;
};
Box.cpp
SomeClass::SomeClass(int something) : something(_something)
{
arr ={16,2,45,65,45};
for (int x = 0; x < 5; x++)
arr[i] = arr[i] * _something;
}
SomeClass::SomeMethod(){
for (int x = 0; x < 5; x++)
DoSomething(arr[i]);
}
SomeClass::DoSomething(int thing){
//whatever
}
How?
#include <iostream>
//#include <initializer_list>
#include <array>
#include <algorithm>
class foo
{
public:
foo() : values({{16,2,45,65,45}})
{
// I left the below commented out in case you want to research more and use other kinds of types for doing it.
//std::initializer_list<int> list = {16,2,45,65,45};
//std::copy(std::begin(list), std::end(list), std::begin(values));
}
void print()
{
std::for_each(std::begin(values), std::end(values),
[](int v) { std::cout << v << ' '; });
}
private:
static const int SIZE = 5;
std::array<int, 5> values;
};
int main()
{
foo fooInstance;
fooInstance.print();
return 0;
}
The above is the best that I could do in a short period of time. I tested with the following compiler. You could use that as a starting point and see if you can learn other ways of doing it. Algorithms such as generate can also be used with lamda expressions in order to generate a controlled set of values (as opposed to a hard coded list as in our examples).
http://www.compileonline.com/compile_cpp11_online.php
You have options for initializing array data members, and two types or array you can use:
Using a C-style array,
struct Foo
{
int a[5] = {1,2,3,4,5}; // initialization at point of declaration
};
struct Bar
{
int a[5];
Bar() : a{1,2,3,4,5} {} // initialization in constructor initialization list
};
Or using an std::array:
struct Foo
{
std::array<int,5> a = {{1,2,3,4,5}}; // initialization at point of declaration
};
struct Bar
{
std::array<int,5> a;
Bar() : a{{1,2,3,4,5}} {} // initialization in constructor initialization list
};
If you can use C++11, there is support for uniform initialization which allows you to assign brace-enclosed lists of values in more contexts than the special case in C.
Coming from a Java, PHP background, I am trying to get into C++. I would like to store an array in a struct. My problem is specifying the size of the array after initialising the struct.
Here's my code for the struct:
struct SpriteAnimation {
// ...
int parts; // total number of animation-parts
unsigned int textures[]; // array to store all animation-parts
// ...
};
And here for the main function:
SpriteAnimation bg_anim;
bg_anim.parts = 3;
unsigned int *myarray = new unsigned int[bg_anim.parts];
bg_anim.textures = myarray;
What do I need to change to fix this?
In modern C++, you would use a dynamic container for the inner "array":
struct SpriteAnimation {
std::vector<unsigned int> textures; // array to store all animation-parts
size_t num_parts() const { return textures.size(); }
};
This is by far safer and more modular than anything you could try with manually allocated storage. Usage:
SpriteAnimation x;
x.textures.push_back(12); // add an element
x.textures.push_back(18); // add another element
SpriteAnimation y = x; // make a copy
std::cout << "We have " << x.num_textures() << " textures." std::endl; // report
struct SpriteAnimation {
// ...
int parts; // total number of animation-parts
unsigned int * textures; // array to store all animation-parts
// ...
};
You can use type name[] syntax only if you declare members inline.
Size of a struct must be known at a compilation time.
I worked around the issue through following code.It might be having design issues so please look it up the following code works for me.
#include <iostream>
using namespace std;
struct lol {
// ...
int parts; // total number of animation-parts
unsigned int *texture; // array to store all animation-parts
// ...
};
int main() {
// your code goes here
lol bg_anim;
bg_anim.parts = 3;
unsigned int *myarray = new unsigned int[bg_anim.parts];
bg_anim.texture = myarray;
return 0;
}
Forgive me for using lol instead of your specified name.Do tell me any issues.And help me if there are other issues in my code.
Thank you !! :)
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.