Access values from CArray pointer - c++

I have a class which has a CArray object, I need to get values from this CArray to another class, but so far have failed to do so.
class CTempGridClass: public CTableCtrl {
public:
CArray<CArray<float,float>, CArray<float,float>&> *m_row2;
};
class CCorePassageAreasPage : public CDialog {
DECLARE_DYNCREATE(CCorePassageAreasPage)
public:
enum { IDD = IDD_CORE_PASSAGE_AREA };
CArray<CArray<float,float>, CArray<float,float>&> m_row;
CTempGridClass Grid;
};
BOOL CCorePassageAreasPage::OnSetActive() {
Grid.m_row2 = &m_row;
}
How can I access m_row2 values? I tried
float x = m_row2[0][1];
but this gives out an "'initializing' : cannot convert from 'CArray' to 'float'" error. I can do the above assignment to m_row without any errors.
I know that I can avoid this by using a vector instead, but the 'CCorePassageAreasPage' is created by someone else and I don't want to change it.

m_row2 is a pointer; so m_row2[nRow] would refer to element nRow of an array of CArray, if it pointed an array. Since it (presumably) only points to a single object, it just accesses invalid memory.
You almost certainly don't want it to be a pointer; since you say the class "has" it, it should just be a member with no unnecessary indirection.
If you do want a pointer for some reason, then you'll need to dereference it to access the array it points at:
float x = (*m_row2)[nRow][j];

Related

Declare an array as a class member

I build two classes, cell, and HashTable, I want to declare an array of cells as a hashTable class member.
I want to do it with primitive vars like int,chars, like I declare array of cars as a hashTable class member.
I tried to declare an array of cells in some ways :
1.
class HashTable{
public:
int size;
int numOfKeys;
Cell* table = new Cell[10];
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0) {
table = new Cell[10];
}
2. class HashTable{
public:
int size;
int numOfKeys;
Cell* table = new Cell[10];
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0),table(new Cell[10]) {
}
I try to declare it in the constructor but it doesn't work.
How am I supposed to define this array?
Thanks !
I don't see any error , but I can see the array of cars but not the array of table
class Cell
{
public:
AVLTree<Player*>* AllPlayers;
int treeSize;
Cell() : treeSize(0) {
AllPlayers = new AVLTree<Player*>();
}
~Cell(){
delete AllPlayers;
};
Cell(const Cell &sec) = default;
Cell &operator=(const Cell &sec) = default;
void reinsert(Player* pl)
{
treeSize++;
AllPlayers->root = AllPlayers->insert(AllPlayers->root, pl,NULL);
}
int insert(Player* pl)
{
if (!(AllPlayers->findNode(AllPlayers->root,pl)))
{
AllPlayers->root = AllPlayers->insert(AllPlayers->root,pl,NULL);
treeSize++;
return 0;
}
return -1;
}
int remove(Player* pl)
{
AllPlayers->root = AllPlayers->remove(AllPlayers->root,pl);
treeSize--;
return treeSize;
}
};
class HashTable{
public:
int size;
int numOfKeys;
Cell* table;
int cars[4];
//static void resize(HashTable &ht);
static void reinsert(Cell* new_table, int new_size, Node<Player*> *data);
HashTable() : size(10), numOfKeys(0) {
table = new Cell[10];
}
~HashTable() { delete[] table; }
Fear not! You have an array of ten Cells pointed at by table.
table is a pointer. It holds an address, nothing more. A pointer knows only where an object is (note that the object may have been subsequently destroyed, a pointer has no way of knowing, or the pointer may not have been initialized). If the object referenced to by the pointer is an array, the pointer has no way to know how many items are in the array. The IDE cannot show that there are ten items in the array pointed at by table because all it knows is the pointer and the pointer does not know. If you want the IDE to display what is in those ten Cells, you need to set up what are commonly called "watch expressions" for each subobject in the array or play games with casting to tell the watch expression how to interpret the object at the pointer.
cars is an array. Arrays represent the whole whole array. They know their size, their dimensions and all of the data in the array. The IDE can show you all of the items in the cars array because cars knows all that there is to know.
If you know you will always and forever have 10 Cells, get rid of the pointer and define an array. If you don't know the size, you'll have to live with what the IDE can show you.
Side note: Some IDEs are smart enough to interpret a std::vector and can display the objects in the std::vector. Consider using std::vector instead of a dynamic array where possible. Intelligent handing in IDEs is but a small benefit of std::vector.
Side note: When I say object, I mean it in the C++ definition of object, not in the OOP sense of an instance of a class.

Append and clear for a list c++

I'm trying to realize two methds append() and clear().
In appened(), I need to newPoint to the end of a list. If the list is empty, then adds newPoint as the first(and only) point in the list.
In clear(),I need to remove all the points in a list.
Can you give me some advice to realize appened and clear.
Here is a code:
//
#pragma once
const int maxListSize = 10;
class Point
{
private:
float x;
float y;
public:
Point(float x0 = 0, float y0 = 0)
{
x = x0;
y = y0;
}
};
class PointList
{
private:
//Data members
int size;
int cursor;
Point points[maxListSize];
public:
PointList();
//List Manipalution operations
void append(Point newPoint);
void clear();
~PointList();
};
*I don't need you to write everything for me, just give me some advice. I would like to realize it by myself. Thank you for helping.
Since you store your list elements by value (Point points[maxListSize]),
it is quite easy to do:
PointList() :size(0) {}
void append(Point newPoint) { points[size++] = newPoint; }
void clear() { size = 0; }
This assumes that your Point object doesn't manage any resource, which is true for this particular example. Otherwise, inserted Point objects should be destroyed in clear.
To get the semantics that you're probably expecting for appending new items, and clearing out existing items, I suggest you look at the placement new operator, and manually calling the destructor of an item in the list.
Currently your class will construct all of the items in the list when you create the list. This can be quite time consuming for complex structures. Then, instead of the constructor for your elements being called, you'll instead be calling the copy-assignment operator, as the items are already constructed.
If you store your array as
char * points[sizeof(Point)*maxListSize];
Any only initialize the items when they're actually added, you avoid the construction cost when you create the list.
Your append function takes it's argument by value. Instead, I recommend you have two append functions. One that takes const&, and the other that takes an rvalue-reference. Then, inside the append function, call the placement new operator on the address of the next location in your array.
To clear the array, simple call the destructor for each element in the array one at a time.

C++ - Proper method to use delete while creating a vector of class objects

I saw a few examples of creating a vector of class objects and many of them uses a pointer and new keyword. However, in many cases the delete is not used to free up memory allocated by new. I would like to know if the following piece of code uses delete properly.
I have a class Marker:
class Marker{
public:
Marker(int, float, float);
int marker_id();
private:
int id;
float mx;
float my;
};
It's constructor is:
Marker::Marker(int idno, float x, float y){
//ctor
id = idno;
mx = x;
my = y;
}
I need a vector marker_vec with objects or instances of Marker class. Hence, I wrote the following piece of code:
vector <Marker> marker_vec;
Marker *m = new Marker(last_id, m_x, m_y);
marker_vec.push_back(*m);
delete m;
If I use the above code in a loop to create marker_vec[0] and marker_vec[1], I believe that the delete wouldn't delete them and will only free up the pointer m. Is there any disadvantages for the above method?
This piece of code is alright, since when you push_back, the contents referenced by the m pointer will be copied and added as the last element of the vector. You're doing good by deallocating the memory you set properly (for every new there is a corresponding delete).
vector <Marker> marker_vec;
Marker *m = new Marker(last_id, m_x, m_y);
marker_vec.push_back(*m);
delete m;
I just think it's unnecessary for you to use pointers in this case having one type of Marker class and your std::vector of type <Marker>.
I would personally improve the implementation of this code to being statically instantiated. It's simple and cleaner in this case:
vector <Marker> marker_vec;
Marker m(last_id, m_x, m_y);
marker_vec.push_back*m);
However, if you maybe had inheritance like different type of markers:
class HighlighterMarker : public Marker { };
and
class PenMarker: public Marker { };
Only then, it'd make sense for you to use dynamic memory and your vector to be declared as:
std::vector <Marker*> marker_vec. This one can store all your references to any type of derived class Marker,

Eclipse fails to resolve a method from a vector made of class pointers (C++)

I have a class that looks like this:
enum DATA_TYPE {bla, bla2};
class Mem_Data
{
private:
DATA_TYPE m_eType;
uint32 m_nLineAddr;
uint32 m_nPhysAddr;
uint32 m_nSize;
int m_nIndex;
public:
Mem_Data(DATA_TYPE eType, uint32 nLineAddr,uint64 nPhysAddr,uint64 m_nSize, int nIndex = 0);
DATA_TYPE GetType();
int GetIndex();
uint32 GetLineAddr();
uint32 GetPhysAddr();
};
I then create a vector that is made from pointers of this class:
Vector<Mem_Data *> m_dataVec;
m_dataVec.push_back(new MemData());
m_dataVec.push_back(new MemData());
m_dataVec.push_back(new MemData());
(Of course I put data to match my constructor but this is just an example)
But when I try to access a function from the class inside the vector Eclipse fails to resolve it.
m_dataVec.front()->GetType()
The above fails to resolve.
However this seems to work:
Mem_Data *p = m_dataVec.front();
p->GetType();
This does resolve but it seems inelegant as it forces me to add another variable and not access the class instance directly.
Would appreciate any suggestions.
vector.begin() returns an iterator.
In order to get access to the data stored in the vector, or more specifically, to the data the iterator points to, you need to dereference the iterator.
you do this with either operator*() or operator->().
In your example, you would do this as follows:
auto iterator = m_dataVec.begin(); // get iterator from vector
Mem_Data *p = *iterator; // dereference iterator to get Mem_Data pointer
You can dereference begin() in one line using *:
*m_dataVec.begin() // this is a Mem_Data pointer
You can then get access to the data the pointer is pointing as using either * or ->:
(*m_dataVec.begin())->GetType();
Note here the parens around (*m_dataVec.begin()) are necessary because of operator precedence.
Another way to do the same is double-dereference, which would give you access to Mem_Data&:
**m_dataVec.begin().GetType(); // double deref - 1st the iterator, then the pointer
This is what I ended up using:
((Mem_Data*)cve.m_dataVec[0])->GetLineAddr()
It seems that the vector implementation kept trying to use the consts [] operator instead of the normal [] operator, and this solved it.

Initializing a pointer array of objects

So I have the following code
class UserDB
{
private:
AccountInfo* _accounts[200] ; // store up to 200 accounts
public:
UserDB();
virtual ~UserDB();
}
UserDB::UserDB(){
//code for initializing it to null
}
UserDB::~UserDB(){
delete [] _accounts;
}
So basically I am trying to find this code to initialize _accounts to null but I cannot find a real answer, all the guides in the internet either say how to initialize an array, an object, or a pointer, but not something that is all three altogether, and even less how to initialize this kind of pointer to null, even whatever they are initializing [in the guides] looks very confusing, so I come once again to ask for help here.
Also, AccountInfo is just any random class.
use std::array or std::vector.
you don't delete[] _accounts because the array is a value -- it is an array of pointers. IOW, its size is not equal to a pointer.
Here's a std::vector approach:
class UserDB {
private:
std::vector<AccountInfo*> _accounts;
public:
UserDB() : _accounts(200, 0) {}
virtual ~UserDB() {}
};
However, you may prefer to use the vector's default initializer so you can use it to determine the number of accounts it holds.
Update in response to comments below:
Although there are reasons to hold an array of AccountInfo* pointers, you may also consider std::vector to hold an array of AccountInfos values:
class UserDB {
private:
std::vector<AccountInfo> _accounts;
public:
UserDB() : _accounts() {}
virtual ~UserDB() {}
void appendAccountInfo(const AccountInfo& info) {
this->_accounts.push_back(info);
}
};
std::vector will handle all your allocation and reallocation needs for you. It's also nice because it's dynamically resizable, and you won't be constrained to a fixed number of AccountInfos.
create a constant instead of the magic number 200 (not really necessary but it makes the code more readable and safer when later changing)
const int numberOfAccounts = 200;
AccountInfo* _accounts[numberOfAccounts]
UserDB::UserDB()
{
for (int i = 0; i < numberOfAccounts; ++i)
{
_accounts[i] = 0;
}
}
now you have you 200 zeroed pointers.
also have a habit of putting private members at the end of the class and public at the start,
especially by bigger classes you want to see the public stuff first, the private stuff you normally
don't want somebody to mess with.
class C
{
public:
protected:
private:
};
I do remember having read that this would work:
UserDB():_accounts(){}
This should initialize the contents to NULL