Copy Constructor Pointer Object - c++

I have the following class with the 2 pointers to block
#ifndef SCORING_H
#define SCORING_H
#include "Block.h"
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
class Scoring
{
public:
Scoring(Block *, Block*, string, string, double);
virtual ~Scoring();
Scoring(const Block& b1, const Block &b2);
private:
Block * b1;
Block * b2;
string path1;
string path2;
double val;
};
#endif // SCORING_H
Class Block is the following:
class Block {
public :
///constructo
Block(double, double, double, double, int, vector<LineElement*>);
///Setter functions
void setID(int);
void setTop(double);
void setLeft(double);
void setRight(double);
void setBottom(double);
void setLine(vector<LineElement*>);
int getID();
double getTop();
double getLeft();
double getBottom();
double getRight();
vector<LineElement*> getLine();
private:
int id;
vector<LineElement*> Listline;
double top;
double left;
double bottom;
double right;
};
#endif // ELEMENT_H_INCLUDED
I want to know, Should I construct a copy constructor for "Block * b1;Block * b2" and how can I treat these 2 points in the class scoring.h?
Thank you.

If you create a constructor other than plain and simple Block::Block(const Block&) then it's not a copy-constructor. If you want to make a constructor in Scoring taking two Block pointers it's most definitely is not a copy-constructor.
If you want a copy-constructor in Scoring it should be like this:
class Scoring
{
// ...
Scoring(const Scoring& other);
// ...
};
Then in that constructor you copy from other:
Scoring::Scoring(const Scoring& other)
: b1(new Block(*other.b1)),
b2(new Block(*other.b2)),
path1(other.path1),
path2(other.path2),
val(other.val)
{
}
Of course, you should probably make a copy-constructor for the Block class too, as it contains a vector of pointers, and if you don't you will have two vectors with pointers pointing to the same objects, and that will be bad when you delete these objects in one vector but not the other.

Related

C++ class member not initialized (at constructor, but does at initialize method)

I have a C++ class with two constructors (a default one and another with arguments). In order to reuse code, I avoided initializing class members at the constructor level, and I'm doing it in an Initialize method instead, which I am calling from both constructors. This way, I was hopping to minimize code lines and repeated code:
Location::Location(){
double pos[POSITION_SIZE] = {0};
this->Initialize(const_cast<char*>(""), const_cast<char*>(""), pos);
}
Location::Location(char *id, char *code, double pos[POSITION_SIZE]){
this->Initialize(id, code, pos);
}
void Location::Initialize(char *id, char *code, double pos[POSITION_SIZE]){
strcpy(this->ID, id);
strcpy(this->code, code);
this->position[0] = pos[0];
this->position[1] = pos[1];
this->position[2] = pos[2];
this->attribute1 = 0;
this->attribute2 = 0;
}
header:
class Location{
public:
Location();
Location(char *id, char *code, double pos[POSITION_SIZE]);
private:
// This method initializes the location attributes given as parameters
void Initialize(char *id, char *code, double pos[POSITION_SIZE]);
// Name/identifier of the location
char ID[ID_LENGTH];
// FIR identifier
char code[ID_LENGTH];
// Location's coordinates (lat, lon, alt)
double position[POSITION_SIZE];
// Attribute 1
double attribute1;
// Attribute 2
double attribute2;
};
I know that using initialize methods is a bad praxis when used because old school coding style or avoiding the usage of exceptions at constructor for example. But my goal here was reducing code, so unless some guru of stackoverflow says the opposite, I think it is not wrong (but I'm here to learn, so please destroy all my convictions).
The problem is that I'm getting a warning for not initializing class members within the cosntructor. The compiler doesn't like them to get initialized at the Initialize method. So, any way of making the compiler happy? Should I forget aboput Initialize method usage?
I would use constructor delegation, something like:
#include <iostream>
using namespace std;
class foo
{
public:
foo()
: foo(1, "2", 3.) // delegate to the other constructor with defaults...
{ }
foo(int a, std::string b, double c)
: _a(a), _b(b), _c(c)
{ }
private:
int _a;
std::string _b;
double _c;
};
int main() {
foo f1{};
foo f2{1, "3", 4.};
return 0;
}
With the caveat that you can use atleast c++11...

Reference to member function

first of all I know that this is not possible in C++. But I hope someone can tell be a workaround for my problem. I have a class which represents a mathematical function:
class myClass:
{
private:
public:
myClass() {};
double value(double, double){ /* doing some complicated calculation here */} };
double integrate { /*calc*/ return integral; };
}
In integrate() I want to create a struct with a reference to value(). The struct is defined as follows:
struct gsl_monte_function_struct {
double (*f)(double * x_array, size_t dim, void * params);
size_t dim;
void * params;
};
(I need this struct to call the Monte-Carlo integration routines from GSL)
As said before I know that this is forbidden in C++. But is there any possibility to use gsl_monte_function_struct with a member function of myClass? If it is not possible that myClass can integrate itself, is it possible to call gsl_monte_function_struct from outside the class with value() as reference? Thanks in advance!
If understand you corretly, you want a pointer to a member function of myClass. You can achieve this by declaring the member function pointer as:
double (myClass::*value)(double,double)
This function can later be called on an instance as:
(instance.*value)(x,y);
Alternatively you can use std::bind to create a function object which can be called as an ordinary function without having to keep track of the instance on which it is called after the call to std::bind:
auto& value = std::bind(myClass::value, instance);
// ....
value(x,y);
Ok so far I found two solutions:
1) (General solution) Using an abstract base class which has a static pointer to the current instance and a static function that calls a function of the derived class. The static function can be used with a function pointer.
Example:
struct gsl_monte{
double (*f)(double y);
};
class myBase {
private:
static myBase* instance;
public:
myBase(){};
static void setInstance(myBase* newOne);
virtual double value(double x) =0;
static double callValue(double x);//{return value(x);}
};
class myClass : public myBase {
public:
myClass(){};
double value(double x) { return x; };
};
myBase* myBase::instance = new myClass();
double myBase::callValue(double x){return instance->value(x);}
void myBase::setInstance(myBase* newOne){instance=newOne;};
double g(double xx) {return xx;};
int main(int argc, char** argv ){
double x[2]; x[0]=1.3; x[1]=1.3;
myClass* instance = new myClass();
myBase::setInstance(instance);
instance->value(3);
std::cout << "Test " << myBase::callValue(5) << std::endl;
gsl_monte T;
T.f=&myBase::callValue;
double (*f)(double y, void*) = &myBase::callValue;
}
2) (Solution specific to my problem) Fortunatly the desired function accepts a parameter pointer, which I can use to pass the current object:
#include <iostream>
#include <functional>
using namespace std::placeholders;
struct gsl_monte{
double (*f)(double y, void*);
};
class myClass {
public:
myClass(){};
double value(double x) { return x; };
};
double valueTT(double x, void* param) { return static_cast<myClass*>(param)->value(x); };
int main(int argc, char** argv ){
double x[2]; x[0]=1.3; x[1]=1.3;
myClass* instance = new myClass();
instance->value(3);
gsl_monte T;
T.f=&valueTT;
double (*f)(double y, void*) = &valueTT;
}

C++ friend function not working

I am new to C++ and have been trying to get my head around classes in c++. Recently I tried out this program and instead of returning an integer 9, it returns some garbage value. Can someone please help me out
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
class abc;
class xyz
{
int a;
public:
friend int add(xyz, abc);
friend void setval(xyz, int, abc, int);
};
class abc
{
int b;
public:
friend int add(xyz, abc);
friend void setval(xyz, int, abc, int);
};
int add(xyz V1, abc V2)
{ return (V1.a + V2.b);}
void setval(xyz v1, int v11, abc v2, int v22)
{v1.a = v11; v2.b = v22; }
int main()
{
xyz A;
abc B;
setval(A, 4, B, 5);
cout<<add(A, B)<<endl;
return(0);
}
This is happening because you are passing the arguments to setval function by value which will modify the copy of the object that you have passed.
Use the following signature instead:
void setval(xyz& v1, int v11, abc& v2, int v22);
This way you will be sending the reference to your objects instead of copies of those objects made in some separate blobs of memory. Thus, the objects created in your main function will be assigned the values.
friend void setval(xyz, int, abc, int);
Your set functions sets value to an copy of the passed object not the passed object. You need to pass by reference.
friend void setval(xyz &, int, abc &, int);
^^^^^^ ^^^^^^
I may as well suggest starting with a good book:
The Definitive C++ Book Guide and List

C++ Runtime Error on push_back for a vector of custom objects

In my class, when I try to push any object onto the vector myCache, I get a runtime error. I know I'm initializing the vector properly, and am stumped about why this is happening.
#ifndef CACHE_H
#define CACHE_H
#include <iostream>
#include "cacheblock.h"
using namespace std;
class Cache
{
public:
Cache(int rows, int numWords);
~Cache();
CacheBlock getBlock(int index);
private:
vector<CacheBlock> *myCache;
};
#endif
and
Cache::Cache(int rows, int numWords)
{
myCache = new vector<CacheBlock>;
CacheBlock test(rows, 0, 0);
myCache->push_back(test);
/*
for (int i = 1; i < rows; i++)
{
myCache->push_back(test);
cout << "inside loop\n\n";
}
*/
}
CacheBlock.h:
class CacheBlock
{
public:
CacheBlock(int numWords, int newIndex, int tagNum);
CacheBlock(const CacheBlock &newCacheBlock);
~CacheBlock();
void setData(int numWords, int newIndex, int tagNum);
private:
bool valid;
int index;
int tag;
vector<int> *dataWords;
};
Can anyone help?
Presumably there is a working Copy Constructor for CacheBlock?
EDIT: thanks for posting the additional code.
If the destructor for CacheBlock cleans up the allocated vector<int> *dataWords by deletion, then the copy constructor will need to "deep copy" the vector of dataWords. Without this deep copy, when the CacheBlock is copied, there will be two instances of CacheBlock with the same pointer to the vector<int>. When the first instance is cleaned up, the second one will end up with a stray pointer to the now-deleted copy.
It's worthy of mention, as implied by the comment asking why the vectors<> are being allocated from the heap, that had they not been allocated from the heap, but had been mere member variables, none of these problems would have occurred.
To wit:
#ifndef CACHE_H
#define CACHE_H
#include <iostream>
#include "cacheblock.h"
using namespace std;
class Cache
{
public:
Cache(int rows, int numWords);
// no longer need a destructor, as the auto-generated one by the compiler suffices
// ~Cache();
// potential optimization to return by const reference, rather than by copy
const CacheBlock& getBlock(int index) const;
private:
vector<CacheBlock> myCache;
};
#endif
and
Cache::Cache(int rows, int numWords)
{
// no longer need to construct the vector
// myCache = new vector<CacheBlock>;
CacheBlock test(rows, 0, 0);
myCache->push_back(test);
}
CacheBlock.h:
class CacheBlock
{
public:
CacheBlock(int numWords, int newIndex, int tagNum);
// no longer need a copy constructor
// CacheBlock(const CacheBlock &newCacheBlock);
// no longer need a destructor, as the compiler-generated one will suffice
// ~CacheBlock();
void setData(int numWords, int newIndex, int tagNum);
private:
bool valid;
int index;
int tag;
vector<int> dataWords;
};

C++ Circular declaration

I have a couple of cases of circular declaration in my class delaractions in my main (global) header.
#include <cstdlib>
#include <iostream>
using namespace std;
enum piece_t {BLACK, WHITE, EMPTY, WALL}; //wall is area out side of board (board array is 21x21 but only 19x19 is playable)
enum dir_t {ABOVE,BELOW,LEFT, RIGHT}; //shall i overload ! or - operatior? !LEFT==RIGHT?
struct nextPoint_t //should be implimented with references, but need to practice pointer
{
point_t* above;
point_t* below;
point_t* left;
point_t* right;
};
class point_t
{
private:
piece_t mType; //what sort of point this is
int mLiberties;
nextPoint_t mAdjacent; // points to adjacent points
bool mLibertiesCounted; // keeps track of if liberties have been counted, for mCountLiberites() (sets), is reset by mUpdateLiberites();
int mCountLiberties(); //counts this point's liberites, by calling count on mAdjacent points etc.
void mSetPos(int xPos, int yPos, board_t theBoard); //sets up mAdjacent to point to adjacent points,
void mSetStructureLiberties(int numLibs); // Sets this squares liberites then calls this on all adjacent squares
public:
point_t ();// parameterless constructor, for arrays
void mSetUp(int xPos, int yPos, board_t theBoard);// sets up mType then calles setPos iFF not WALL type
point_t (int xPos, int yPos, board_t theBoard); //constructor, takes it's position in the grid as a parameter
void mUpdateLiberties(); // calles countLiberties then, updates liberites on whole of connected structure, by operating pon all conencted points
};
class board_t
{
private:
point_t mArray [21][21];
public:
board_t(); //constructor, sets up board by operating on the point_t's
};
Don't worry about the comments there for my reading, I know what I mean.
I thought I could fix it with forward declarations, but they don't seem to work, it just thinks I'm redeifining the classes
Alright, after considering the comments and doing a test on my own, the real answer :
You must use forward declaration, no more. :)
#include <cstdlib>
#include <iostream>
class point_t;
class board_t;
/* Rest of the code stay the same */
The forward references in your code seems to be to board_t and point_t, which is resolved by forward declaring them.
Since you reference board_t in member function declarations of point_t, you cannot define the member functions right away in point_t. Their definitions have to appear after board_t is defined. So you have to either move the definition of the functions into the cpp file, or you have to move their definition in the header after definition of board_t whichever suites you more. point_t is only used as a pointee type in nextPoint_t, so we don't have the same problem for it here:
class point_t; // used by nextPoint_t
class board_t; // used by point_t
struct nextPoint_t //should be implimented with references, but need to practice pointer
{
point_t* above; // goes without problems - doesn't need definition of point_t
point_t* below;
point_t* left;
point_t* right;
};
class point_t
{
private:
piece_t mType;
int mLiberties;
nextPoint_t mAdjacent;
bool mLibertiesCounted;
int mCountLiberties();
void mSetPos(int xPos, int yPos, board_t theBoard);
void mSetStructureLiberties(int numLibs);
public:
point_t ();
void mSetUp(int xPos, int yPos, board_t theBoard);
point_t (int xPos, int yPos, board_t theBoard);
void mUpdateLiberties();
};
class board_t
{
private:
point_t mArray [21][21];
public:
board_t();
};
Definition at the end of the header looks like
// define it either inline in the header, or non-inline in a cpp file
inline void point_t::mSetPos(int xPos, int yPos, board_t theBoard) {
/* some work... */
}
// same for mSetUp...
Nonetheless i would recommend you to use const references to pass the board to point_t's member functions, but this is not a requirement for your code to work. Declarations go fine with incomplete parameter types.
if you write before your struct
class point_t;
that should do the trick.
Although I am not quite sure why your organize your class like that. You already have an array mArray in your board so there is no real need to have pointers to adjacent points inside each point_t.
EDIT: as the other poster said before you need to use pointers.
Just add this above struct nextPoint_t
enum piece_t {BLACK, WHITE, EMPTY, WALL};
enum dir_t {ABOVE,BELOW,LEFT, RIGHT};
class point_t;
class board_t;
struct nextPoint_t
{
point_t* above;
point_t* below;
point_t* left;
point_t* right;
};
And change any reference to a board_t to a board_t*
void mSetUp(int xPos, int yPos, board_t* theBoard);
#include <cstdlib>
#include <iostream>
enum piece_t {BLACK, WHITE, EMPTY, WALL}; //wall is area out side of board (board array is 21x21 but only 19x19 is playable)
enum dir_t {ABOVE,BELOW,LEFT, RIGHT}; //shall i overload ! or - operatior? !LEFT==RIGHT?
class point_t;
struct nextPoint_t //should be implimented with references, but need to practice pointer
{
point_t* above;
point_t* below;
point_t* left;
point_t* right;
};
class board_t;
class point_t
{
private:
piece_t mType; //what sort of point this is
int mLiberties;
nextPoint_t mAdjacent; // points to adjacent points
bool mLibertiesCounted; // keeps track of if liberties have been counted, for mCountLiberites() (sets), is reset by mUpdateLiberites();
int mCountLiberties(); //counts this point's liberites, by calling count on mAdjacent points etc.
void mSetPos(int xPos, int yPos, const board_&t theBoard); //sets up mAdjacent to point to adjacent points,
void mSetStructureLiberties(int numLibs); // Sets this squares liberites then calls this on all adjacent squares
public:
point_t ();// parameterless constructor, for arrays
void mSetUp(int xPos, int yPos, const board_t& theBoard);// sets up mType then calles setPos iFF not WALL type
point_t (int xPos, int yPos, const board_t& theBoard); //constructor, takes it's position in the grid as a parameter
void mUpdateLiberties(); // calles countLiberties then, updates liberites on whole of connected structure, by operating pon all conencted points
};
class board_t
{
private:
point_t mArray [21][21];
public:
board_t(); //constructor, sets up board by operating on the point_t's
};