I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
class celement
{
public:
int x[3];
...
class vec
{
public:
std::vector<celementv;
...
void vec::addelement()
{
celement t;
v.push_back(t);
}
void vec::buildmono()
{
addelement();
v.end() -x[0] = -1;
...
void vec::buildmono()
{
for (i = 0; i < 10; i++)
buildmono();
Later I look through v and none of x[0]s are -1 they are all 0.
for (i = 0; i < 10; i++)
cout << v[i].x[0] ..
If there is no obvious explanation then I can post more code. 8 1679
Hi,
I didn't look at your code carefully (it's quite late here) but I saw
v.end()->
v.end() is pointing one past the last element, i.e.illegal
make that
v.rbegin()->
Regards, Ron AF Greve http://moonlit.xs4all.nl
<im*****@hotmail.co.ukwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
>I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
class celement
{
public:
int x[3];
..
class vec
{
public:
std::vector<celementv;
..
void vec::addelement()
{
celement t;
v.push_back(t);
}
void vec::buildmono()
{
addelement();
v.end() -x[0] = -1;
..
void vec::buildmono()
{
for (i = 0; i < 10; i++)
buildmono();
Later I look through v and none of x[0]s are -1 they are all 0.
for (i = 0; i < 10; i++)
cout << v[i].x[0] ..
If there is no obvious explanation then I can post more code.
Moonlit wrote:
make that
v.rbegin()->
Thanks, that worked, although I found it easier to use push_back(x)
with x already set to what I wanted. im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
std::vectors don't store classes, they store instances of a class.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.
The celement class should encapsulate your integers and in a case like
this you should keep the integers seperate. Why? Because then you'll
have control over what a default object looks like without having to
initialize the array in its ctor. Use an init list instead.
#include <iostream>
#include <ostream>
#include <vector>
class celement
{
int x, y, z;
public:
celement() : x(0), y(0), z(0) { } // default ctor w init list
celement( int x_, int y_, int z_ ) : x(x_), y(y_), z(z_) { }
~celement() { }
/* friend function */
friend
std::ostream& operator<<( std::ostream&, const celement& );
};
/* global op<< oveload for celement */
std::ostream& operator<<( std::ostream& os, const celement& ce )
{
os << "x = " << ce.x;
os << ", y = " << ce.y;
os << ", z = " << ce.z;
return os << std::endl;
}
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};
int main()
{
vec container(5);
container.push_back( celement(10,11,12) );
std::cout << "container's size = " << container.size();
std::cout << std::endl;
for ( size_t i = 0; i < container.size(); ++i)
{
std::cout << "container[ " << i << " ] ";
std::cout << container[ i ];
}
return 0;
}
/*
container's size = 6
container[ 0 ] x = 0, y = 0, z = 0
container[ 1 ] x = 0, y = 0, z = 0
container[ 2 ] x = 0, y = 0, z = 0
container[ 3 ] x = 0, y = 0, z = 0
container[ 4 ] x = 0, y = 0, z = 0
container[ 5 ] x = 10, y = 11, z = 12
*/
I'm ignoring the need that celement should have and assignment op for
now.
Salt_Peter wrote:
im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
std::vectors don't store classes, they store instances of a class.
OK, my bad wording.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.
Do you mean I have to provide a constructor ?
Even if I assigned afterwards it could cause problems ?
celement c;
vec.push_back(c);
... later c out of scope
vec.rbegin() -x[0] = 10;
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};
Won't you get all these anyway ? Why "present" them to the compiler ? im*****@hotmail.co.uk wrote:
Salt_Peter wrote:
im*****@hotmail.co.uk wrote:
I have a std::vector with each element being a class, I push_back
elements and then store values in the class object, later I look at
these objects and the values are null. In essence:
std::vectors don't store classes, they store instances of a class.
OK, my bad wording.
Beware of instances that are default constructed without the use of a
default ctor. You'll get surprises.
Do you mean I have to provide a constructor ?
Even if I assigned afterwards it could cause problems ?
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode. Besides, why assign it later when you can
do it at construction time?
>
celement c;
vec.push_back(c);
.. later c out of scope
vec.rbegin() -x[0] = 10;
It doesn't matter if c is out of scope, the vector stores an
independant copy of it.
>
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector with def
elements
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
celement& operator[]( unsigned index ) { return v[index]; }
};
Won't you get all these anyway ? Why "present" them to the compiler ?
The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements. You could overload a friend operator<< that
iterates through the container seamleassly. The point is that the user
of the class will find it harder to break the container if you protect
its internals.
class vec
{
std::vector< celement v;
public:
vec() : v() { }
vec(size_t sz) : v(sz) { } // preset size of vector
~vec() { }
size_t size() const { return v.size(); }
void push_back( const celement& ce ) { v.push_back( ce ); }
void push_back( int x, int y, int z ) { v.push_back( celement(x, y,
z) ); }
celement& operator[]( unsigned index ) { return v[index]; }
/* friend function */
friend
std::ostream& operator<<( std::ostream&, const vec& );
};
std::ostream& operator<<( std::ostream& os, const vec& r_v )
{
std::cout << "container's size = " << r_v.v.size();
std::cout << std::endl;
typedef std::vector< celement >::const_iterator VIter;
VIter iter = r_v.v.begin();
for ( iter; iter != r_v.v.end(); ++iter )
{
os << *iter;
}
return os;
}
int main()
{
vec container;
celement def;
container.push_back( def );
container.push_back( celement(0, 1, 2) );
container.push_back( 10, 11, 12 );
celement ce( 20, 30, 40 );
container.push_back( ce );
// container.v.clear(); // error: vec::v is private
std::cout << container; // one line for output !!!
return 0;
}
/*
container's size = 4
x = 0, y = 0, z = 0
x = 0, y = 1, z = 2
x = 10, y = 11, z = 12
x = 20, y = 30, z = 40
*/
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode.
OK, deceptive, but not particularly unusual in computer systems in
general for initialise values to be non 0 or null.
Besides, why assign it later when you can
do it at construction time?
Constructors that assign values make for nice textbook code, but in
practice if you have objects of any complexity you will probably want
to initialise them from disk ( database etc) probably more than once.
So writing constructor code just makes for more work.
>
The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements.
OK, but why not make a member to "initialise" the object and then call
that from the constructor, that way I don't have to create a new object
just clear it (if neccessary) and call initialise again.
Thanks, for the example. im*****@hotmail.co.uk wrote:
Not neccessarily, but keep in mind that some compilers will default
initialize an integer, for example, to 0 in debug and leave it
unitialized in release mode.
OK, deceptive, but not particularly unusual in computer systems in
general for initialise values to be non 0 or null.
Note that released, optimized code does not initialize at all unless
the ctor does some sort of default construction. Uninitialized objects
are dangerous since the residual bits that are contained in the object
are used if the instance is operated on. That, in essence, is a common
bug.
Doesn't the compiler have to generate a ctor anyway? Same with copy
ctor, d~tor, etc. Why not take control of what the compiler does?
Consider a class that stores a pointer that is left unitialized by
mistake.
What if you wrote the class's ctor to default initialize the pointer to
0 instead?
The moment you, me or an unsuspecting user of the class makes the
mistake of using an instance of P without setting it: the compiler
generates an error that instantly and precisely diagnoses the problem
(null pointer exception). In the long run, its less work cause you
don't have to split your brains looking for the hard to find bugs. Its
safety built-in to the design. And your clients will love you for it.
>
Besides, why assign it later when you can
do it at construction time?
Constructors that assign values make for nice textbook code, but in
practice if you have objects of any complexity you will probably want
to initialise them from disk ( database etc) probably more than once.
So writing constructor code just makes for more work.
The ctor is invoked when reading the data from disk directly. In other
words, when the std::ifstream opens the file: it's contents are
seamlessly used to construct (or even reinitialize) the object or its
elements.
The std::vector is private. The goal is to prevent the user of the
class from directly accessing the components within. As an example, you
can overload vec::push_back(...) to take 3 integer parameters instead
of a celement. You might choose to provide a vec ctor that takes an
array of celements.
OK, but why not make a member to "initialise" the object and then call
that from the constructor, that way I don't have to create a new object
just clear it (if neccessary) and call initialise again.
There is no reason why not. Using some init() member function is
perfectly safe. Which brings us to the core of the issue. The ctor
already supports the init list. I can think of several languages who
would DIE to have the benefits of the init list.
class N
{
int n; // n could be a complex user-type instead
public:
N() : n( initialize() ) { } // perfectly legal
~N() { }
int initialize() const { return 100; } // or whatever is required
};
That way, you can reserve the body of the ctor (and d~tor) for usefull
diagnostics when you are developing the project. as in:
N::N() : n( initialize() ) { std::cout << "N()\n"; }
N::~N() { std::cout << "~N()\n"; }
Which may look trivial at this point but very handy when dealing with
polymorphism and deallocations (you know... memory leaks).
>
Thanks, for the example.
Your welcome, and give yourself some credits. You at least showed some
code.
Salt_Peter wrote:
Note that released, optimized code does not initialize at all unless
the ctor does some sort of default construction. Uninitialized objects
are dangerous since the residual bits that are contained in the object
are used if the instance is operated on. That, in essence, is a common
bug.
OK. But are you saying that even if I set every variable then there
could be some circumstance where it gets corrupted because of no
implemented ctor ?
Doesn't the compiler have to generate a ctor anyway? Same with copy
ctor, d~tor, etc. Why not take control of what the compiler does?
Consider a class that stores a pointer that is left unitialized by
mistake.
What if you wrote the class's ctor to default initialize the pointer to
0 instead?
The moment you, me or an unsuspecting user of the class makes the
mistake of using an instance of P without setting it: the compiler
generates an error that instantly and precisely diagnoses the problem
(null pointer exception). In the long run, its less work cause you
don't have to split your brains looking for the hard to find bugs. Its
safety built-in to the design. And your clients will love you for it.
Yep, default values are great on interfaces.
The ctor is invoked when reading the data from disk directly. In other
words, when the std::ifstream opens the file: it's contents are
seamlessly used to construct (or even reinitialize) the object or its
elements.
I did not know that. I will read up about ifstream.
>
There is no reason why not. Using some init() member function is
<snip>
OK I saw some pitfalls in the C++ faq about one ctor calling another,
but this way will avoid those.
>
Your welcome, and give yourself some credits. You at least showed some
code.
Here is some more, not mine but from supposedly from Stroustrup.
I was wondering you could wrap up std::vector in a similar way..
template < typename T, int max >
struct c_array
{
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
T v[max];
....
google "c_array template c++ Stroustrup" to see the rest. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Generic Usenet Account |
last post by:
To settle the dispute regarding what happens when an "erase" method is
invoked on an STL container (i.e. whether the element is merely
removed from the container or whether it also gets deleted in...
|
by: Steven T. Hatton |
last post by:
This is something I've been looking at because it is central to a currently
broken part of the KDevelop new application wizard. I'm not complaining
about it being broken, It's a CVS images. ...
|
by: Richard Thompson |
last post by:
I've got a memory overwrite problem, and it looks as if a vector has
been moved, even though I haven't inserted or deleted any elements in
it. Is this possible? In other words, are there any...
|
by: Matthias |
last post by:
Hi,
say I have a vector v1:
std::vector<SomeType> v1;
and I need a vector v2 of pointers to v1's elements:
std::vector<SomeType*> v2;
|
by: Alfonso Morra |
last post by:
I have written the following code, to test the concept of storing
objects in a vector. I encounter two run time errors:
1). myClass gets destructed when pushed onto the vector
2). Prog throws a...
|
by: Narf the Mouse |
last post by:
I'm currently working on a roguelike as an excercise in learning c++.
Anyway, I've set up a script parser to check a text file to find out
how many races there are, then dynamically alocate an...
|
by: Christian Bruckhoff |
last post by:
Hi.
Is there a possibility to delete elements out of a vector?
At the moment i do it by copying all needed elements to another vector.
After clearing the old vector i copy them back element by...
|
by: Alan |
last post by:
I am wondering if anyone has any better idea of how to approach
this problem than I do. . . .
I have a vector of items (data). I have to do a pairwise
comparison of each item to each other item...
|
by: arnuld |
last post by:
/* C++ Primer - 4/e
* chapter 4- Arrays & Pointers, exercise 4.28
* STATEMENT
* write a programme to read the standard input and build a vector
of integers from values that are read....
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: Vimpel783 |
last post by:
Hello!
Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
| |