How to assign a pointer to object to another pointer to object of same class? - c++

I have a class called arr and it has a function named _union written like this:
template<class T>
arr<T> *arr<T>::_union(arr<T> B) {
arr<T> *C(this->length + B._length());
bool isPresent = false;
for (int i = 0; i < length; i++)
C->push_back(this->get(i));
for (int j = 0; j < B._length(); j++) {
for (int k = 0; k < C->_length(); k++) {
if (B.get(j) == C->get(k))
isPresent = true;
}
if (!isPresent)
C->push_back(B.get(j));
isPresent = false;
}
return C;
}
The function returns a pointer of an object that was newly created inside this function's scope.
In main function, I wrote code like this :
arr<int> *a3 = a1._union(a2);
a3->display();
When I run, this gives me an error:
What is the problem here? If I don't use any pointers and just return normal object then everything is fine.
Please help me. Also I don't have any copy constructers inside the class. I am just trying to create my own array class with data and functions.

In this code
arr<T> *C(this->length + B._length());
C is a pointer and this->length + B._length() is an integer, hence the error. You can't assign an integer to a pointer.
I guess you were trying to write this code
arr<T> *C = new arr<T>(this->length + B._length());
This code allocates a new arr<T> object using new and calls the a constructor for that object using the integer parameter this->length + B._length().
However is usually a bad idea to use dynamic allocation like this. You should think about redesigning your function without using pointers.
template<class T>
arr<T> arr<T>::_union(arr<T> B) {
arr<T> C(this->length + B._length());
...
return C;
}
This will require you to define a copy constructor etc for arr<T>. But that is normal C++ programming you shouldn't be reluctant to do it.

Related

How to clone objects of unknown dynamic type in C++?

I want to build an array of dervied class objects. I have this base class:
class CandyBox {
protected:
string flavor;
string origin;
public:
inline CandyBox();
inline CandyBox(string s1, string s2);
virtual float getVolume() = 0;
virtual void toString();
CandyBox& operator=(const CandyBox& obj);
virtual ~CandyBox() {}
};
And 2 derived class named class Lindt and class ChocAmor with constructors and methods as well. I'm trying to build now a scratchy list like this:
CandyBox** vec = new CandyBox*[n];
for (int i = 0; i < n; i++) {
cin >> type;
if (strcmp(type, "ChocAmor") == 0) {
vec[i] = new ChocAmor(1, "s", "ro");
}
else vec[i] = new Lindt(1, 2, 3, "f", "it");
}
My question is: What if I want to make another class named CandyBag that contains an attribute like this one CandyBox** vec = new CandyBox*[n]; and I need this method:
CandyBag& operator=(const CandyBag& candy) {
ChocAmor::operator=(candy);
Lindt::operator=(candy);
dim_max = candy.dim_max;
current_dim = candy.current_dim;
vec = new CandyBox*[candy.dim_max];
for (int i = 0; i <= current_dim; i++) {
vec[i] = new ; //HERE I'M STUCK
// because I can't just simply write vec[i] = candy.vec[i], right?
// I need to allocate memory for that vec[i] first
}
return *this;
}
I'm not sure how can I allocate memory for that vec[i] if I don't know the type (if it's a ChocAmor object or a Lindt type in that candy.vec[i]). Should I get an auxiliar array where I should store the types of that array?
All pointers to class-type are the same size and representation. That is essential for opaque pointers to work at all.
If you want to enable cloning the pointed-to objects, add a virtual .clone() to the interface, and/or write your own copying smart-pointer.
Lugging around a pointer to a clone-function or maintaining a mapping from typeid to clone-function would be far more cumbersome, though can be the right solution in other circumstances.
Otherwise, I have a suggestion:
Use smart-pointers, preferably std::unique_ptr, and standard containers, preferably std::vector, to avoid manual memory-management and gain all the associated benefits of using standard types.

Cannot carry object to function properly C++

cliques is my class object. All my class commands work when I use them in my main but for some reason I cannot make changes to my heaps or stacks through my functions. I tried using reference markers on my function parameters but still I'm having ussues. Maybe I've done the reference incorrectly. Does anyone have any ideas what I might be doing wrong?
This is one of my functions:
void UpdateTopK(cliques C, vector<cliques> minheap) {
if (C.getclique_size() < CliqueSize) {
return;
}
else if (minheap.size() < Solutions) {
minheap.push_back(C);
push_heap(minheap.begin(), minheap.end(), min_iterator());
}
else if (minheap.size() == Solutions and C.getMaxclique_prob() > minheap.front().getMaxclique_prob()) {
pop_heap(minheap.begin(), minheap.end(), min_iterator());
minheap.pop_back();
minheap.push_back(C);
push_heap(minheap.begin(), minheap.end(), min_iterator());
}
This is part of my main:
stack <cliques> cstack;
vector<cliques> max_heap;
make_heap(max_heap.begin(), max_heap.end(), max_iterator());
vector<cliques> min_heap;
make_heap(min_heap.begin(), min_heap.end(), min_iterator());
for (int i = 0; i < 5; i++) {
cliques temp(i);
cstack.push(temp);
}
while (!cstack.empty()) {
cliques temp = cstack.top();
cstack.pop();
bool pruned = GenerateChildren(temp, min_heap, max_heap, cstack, graph);
if (!pruned) {
UpdateTopK(temp, min_heap);
}
}
You are passing arguments by value, this implies that parameters are copied before being passed to the function.
So every modification inside a method refers to the local copy only. Try passing values by references, eg:
void UpdateTopK(cliques& C, vector<cliques>& minheap)
^ ^
Mind that an object that needs to be passed to a function without copy and without being edited should be passed by const T& to specify this.

Dynamic Polymorphic Memory Container - Return Value Incorrect

I am currently working on an dynamic memory container.
Basic idea of the class is that you should be able to get the iterator of an object if you really do not know it, without the use of a for loop throughout all the elements to boost performance. The issue I have is the following; when you pass your pointer address to the object you want to get the iterator of it type casts the object into the extended memory containers structures type. This type contains an extra element, an integer. (IteratorNum)
When following the code the integer within the function is set to correct value, as below would be 50. But when the returned value is set into the local integer used in the main function it is 200? I've been adding watches and cannot figure out how it is possible that the function returns 50 but value gets set to 200.
template <typename DataType> class MemoryContainer {
public:
struct LevelData : DataType
{
int element;
};
DataType &New()
{
elements++;
//Reallocate the size of the array
ld = (LevelData*)realloc(ld, sizeof(LevelData) * elements);
//Set the iteratorNumber
ld[elements - 1].element = elements - 1;
return ld[elements - 1];
}
DataType *reserve(int num)
{
return calloc(num, sizeof(DataType));
}
DataType &operator[](int i)
{
return ld[i];
}
bool inArray(DataType *type)
{
//Compare memory addresses and see if it's within.
return (type >= &ld[0]) && (type < &ld[elements - 1]);
}
static unsigned int getIterator(DataType *type)
{
// v this is 50, but in main says returns 200.
return ((LevelData*)type)->element;
}
MemoryContainer()
{
elements = 0;
}
~MemoryContainer()
{
free(data);
}
private:
unsigned int elements;
LevelData *ld;
};
struct Effective
{
//Set it to polymorphic classes
virtual void dummy()
{
}
char * testvar;
Effective(char * c)
{
testvar = c;
}
Effective(){}
};
MemoryContainer<Effective> myContainer;
int _tmain(int argc, _TCHAR* argv[])
{
//Create 200 elements in the array
for(int i = 0; i < 200; i++)
myContainer.New().testvar = "E";
//Add pointer for testing purposes to get the iterator.
Effective * pointer = &myContainer[50];
//Test setting it's value
pointer->testvar = "HEHEHE";
//Get iterator of our pointer in the array
unsigned int i = myContainer.getIterator(pointer);
printf(pointer->testvar);
system("PAUSE");
return 0;
}
I suspect it is the visual studio debugger getting confused between your two i variables. If you print out the value of i, it will print correctly. If you change the name of your variable to something else, the value shows as 50 in the debugger.
That said, your code is a mish-mash of c and c++ and won't work correctly with anything that requires a copy constructor. I would suggest at the very least using new [] rather than realloc.
Also, any user of this collection who tries to store a class with a member variable called element is going to get mighty confused.
The unsigned int i in the main function really has a value of 50, but the debugger is confusing it with the i declared in the for loop (I reproduced this with Visual Studio 2013). If you cout i it will be 50, and if you change the variable name it will show up as 50 in the debugger. I've never seen this problem before so I wonder if it might be due to your use of malloc/realloc/free with C++ objects.

Initialize array of objects from a function (C++)

How do I initialize an array of objects from a function? I'm aware the code below is impractical; I'm just teaching myself C++.
Here is a structure that contains data.
struct pointStruct {
int numberPoints;
Point2D pointArray;
};
The Point2D class has instance variables x and y. In a separate function, I have:
void setPoints(void) {
pointStruct myPointData;
myPointData.numberPoints = 4;
myPointData.pointArray[4]; // here is the problem
// loop with i
myPointData.pointArray[i].x = ...;
myPointData.pointArray[i].y = ...;
}
I'm trying to initialize the array so that I can loop through it and set the x,y coordinates. I've tried using new and some other methods but I can't work through what I need to do. How can I fix this?
When I try to compile this code, I get the error "no match for 'operator[]' in 'myPointData.pointStruct::pointArray[4]' "
You should probably use std::vector like MadScienceDreams suggests.
However, if you want to learn about such things, you could use a pointer instead. For example:
struct pointStruct {
int numberPoints;
Point2D* pointArray;
};
void setPoints(void) {
pointStruct myPointData;
const int num_points = 4;
myPointData.numberPoints = num_points;
myPointData.pointArray = new Point2D[num_points];
for(int i = 0; i < num_points; ++i) {
myPointData.pointArray[i].x = ...;
myPointData.pointArray[i].y = ...;
}
// Do stuff with myPointData...
// Don't forget to have a "delete" for every "new" when you're done.
delete[] myPointData.pointArray;
}
Point2D pointArray;
pointArray is a single instance to Point2D. It is not an array of instances in which case it's type is Point2D [N].
myPointData.pointArray[4];
The above statement calls operator [] taking a parameter of type int, which is not you actually want. Since there is no such member function in Point2D, compiler complains. If you wish to create array of instances, use std::vector<Point2D>.

Initializing struct array with constructor parameters

How can I initialize struct array with parameters in constructor?
Now I have this code:
struct roundMatrix {
private:
int **matrix;
public:
roundMatrix(int teamsNumber) {
matrix = new int*[teamsNumber];
for(int i=0;i<teamsNumber;i++) {
matrix[i] = new int[teamsNumber];
}
}
int addPartners(int first, int second) {
if(matrix[first][second] == -1 && matrix[second][first] == -1) {
matrix[first][second] = 0;
matrix[second][first] = 0;
}
else {
return -1;
}
return 0;
}
};
...
Then I need to inintialize array of roundMatrix with parameter:
roundMatrix rounds[roundsNumber](teamsNumber);
And I got an error:
variable-sized object 'rounds' may not be initialized
One more question. How can I initialize vector with struct and constructor paramaters?
You cannot initialize array in that way. It should be written as:
roundMatrix rounds[roundsNumber] = {teamsNumber, teamsNuber, ...);
Alternatively you need to implement a default constructor for roundMatrix class that will automatically initialize the items in your array.
At first your struct is class. struct should be used in C++ without methods, inheritance, encapsulation and other class's stuff as same as in standart C code.
Next, class names should be in upper camel case: first character of the name should be in uppercase and each new word in the name should begin from uppercase character. By the way your corporate code conventions may override this default convention which uses almost everywhere in C++ code.
And last: in case you have an array of objects of this class you can't call constructor for each object of this class during initialization. You can do something like that:
roundMatrix *rounds = new roundMatrix[roundsNumber];
for(i = 0; i < roundsNumber; i++)
rounds[i] = roundMatrix(teamsNumber);