c++ create a pointer to new class - c++

i have problem withe this code i want to create a pointer to new class
class AnalyzerManager
{
public:
AnalyzerManager();
~AnalyzerManager();
private:
CAnalyzerIF* m_AnalyzerIF = new CAnalyzerIF();
};
it has a compilation error i dont understand how to fix it.
thanks

You have to initialize the pointer in your constructor, not in the class declaration.
AnalyzerManager::AnalyzerManager() : m_AnalyzerIF(new CAnalyzerIF())
{
}
BTW, you might want to look into smart pointers for something like this.

// in AnalyzerManager.h
#include <memory>
class AnalyzerManager
{
public:
AnalyzerManager();
~AnalyzerManager();
// since you are declaring a custom constructor and destructor, you should also define a custom copy-constructor and copy-assignment
AnalyzerManager(const AnalyzerManager& rhs);
AnalyzerManager& operator= (const AnalyzerManager& rhs);
private:
std::shared_ptr<CAnalyzerIF> m_AnalyzerIF;
};
// in AnalyzerManager.cpp
AnalyzerManager::AnalyzerManager() : m_AnalyzerIF(new CAnalyzer)
{
}
AnalyzerManager::~AnalyzerManager()
{
// nothing to do since shared_ptr will clean up the memory for us
}
AnalyzerManager::AnalyzerManager(const AnalyzerManager& rhs) : m_AnalyzerIF(rhs.m_AnalyzerIF)
{
}
AnalyzerManager& AnalyzerManager::operator= (const AnalyzerManager& rhs)
{
m_AnalyzerIF = rhs.m_AnalyzerIF;
return *this;
}

You should start by asking yourself : When do I want this 'new' statement to be executed?
Assuming the answer is on construction of an AnalyzerManager object, then the place for the 'new' is in the constructor of the AnalyzerManager.
Code placed in a constructor that initialises member variables is typically done using the member initialisation list, like this :
AnalyzerManager::AnalyzerManager() : m_AnalyzerIF(new CAnalyzerIF())
{
}
Since you are using 'new' you should consider where the 'delete' will go - presumably in the AnalyzerManager destructor :
AnalyzerManager::~AnalyzerManager()
{
delete m_AnalyzerIF;
}

You cannot do like you have written. I mean right in the declaration.
CAnalyzerIF* m_AnalyzerIF = new CAnalyzerIF();
Instead you have to do that in the constructor AnalyzerManager().
AnalyzerManager::AnalyzerManager()
{
m_AnalyzerIF = new CAnalyzerIF();
// ... and some more initialization ...
}

Related

how to do a vector<class objects*> deep copy

I am having trouble with writing the Rule of three when it comes to vector of pointers to class objects. Searched and examples don't seem to apply. I have these three classes:
class Data
{
private:
map<string, double> m_DataVariables;
public:
Data();
Data(const Data &data);
};
class Sample
{
private:
Data *m_pData;
public:
virtual ~Sample()
{
delete m_pData;
}
Sample();
Sample(const Sample &sample);
};
class BuildTree
{
private:
vector<Sample*> BuildSamples;
public:
BuildTree(vector<Sample*> &Samples);
// This does not compile
BuildTree(const BuildTree& other) : BuildSamples(new(other.BuildSamples))
{
}
~TreeBuilding()
{
for (int i = 0; i < BuildSamples.size(); ++i)
delete BuildSamples[i];
}
void BuildTrees(void);
};
1- Not sure if I am correctly deleting BuildSamples.
2- In the constructor want to do a deep copy of the passed parameter into member variable BuildSamples.
BuildTree::BuildTree(vector<Sample*> &samples)
{
BuildSamples = samples; // This just copies the references
}
How do I write the copy constructor to make a deep copy? What am I missing here?
3- Please note: don't have access to smart pointers, share_ptr or unique_ptr, etc. C++98 is what I have.
Please show the steps required to do this. Really appreciate your time and consideration.
I noted you marked your question as c++98; even if C++98 doesn't support smart pointers in std::, you can certainly use the smart pointers defined in Boost, e.g. boost::shared_ptr.
For example, instead of using raw owning pointers like in vector<Sample*>, you can make your code simpler with
vector<boost::shared_ptr<Sample>>.
In this way, the copy and destruction operations will be automatically implemented under the hood.
You probably want something like:
BuildTree(const BuildTree& other)
{
BuildSamples.reserve(other.BuildSamples.size());
for (std::size_t i = 0; i != other.BuildSamples.size(); ++i) {
BuildSamples.push_back(new Sample(*other.BuildSamples[i]));
}
}
BuildTree(const vector<Sample*> &samples)
{
BuildSamples.reserve(samples.size());
for (std::size_t i = 0; i != samples.size(); ++i) {
BuildSamples.push_back(new Sample(*samples[i]));
}
}
You need to initialise the BuildSamples member as a vector of pointers, and ensure every pointer points at a clone of the objects passed. One way is
BuildTree(const BuildTree& other) : BuildSamples(other.BuildSamples)
{
std::vector<Sample *>::iterator i = BuildSamples.begin(), end = BuildSamples.end();
while (i != end)
{
*i = new Sample(**i);
++i;
}
}
The usage of BuildSamples(other.BuildSamples) initialises BuildSamples with the correct number of elements, but those elements are the same pointers as in other.BuildSamples. This ensures the vector is of the correct size, without worrying about setting the size explicitly. That is a shallow copy. The body of the constructor then sets every element of BuildSamples so it points at a clone of itself - thus completes the deep copy.
The constructor BuildTree(const std::vector<Sample *> &) can be implemented in a similar manner.
Note: given that your class is implementing a non-trivial copy constructor (to do the deep copy) and a destructor to cleanup, you also need to implement an assignment operator BuildTree &operator=(const BuildTree &). For an explanation why, look up the "rule of three".
While dealing with pointers and to avoid crashing of a running program due to destructor being called, Deep copy must be used! deep copy allows creating a new pointer pointing to a newly allocated space. But when passing objects as R-value in vector it is better to use the move constructor.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class example{
private:
int *pointer;
public:
//constructor
example(int d){
pointer = new int;
*pointer = d;
cout<<"Constructor Called"<<endl;
}
// deep copy
example(const example &source){
pointer = new int;
*pointer= *source.pointer;
cout<<"deep copy made"<<endl;
}
// Move Constructor
example(example &&source) noexcept :pointer{source.pointer}{
source.pointer = nullptr;
cout << "object moved"<<endl;
}
// Destructor
~example() {
delete pointer;
cout << "Destroyed"<<endl;
}
};
int main()
{
vector <example> vec;
vec.push_back(example{300});
vec.push_back(example{300});
vec.push_back(example{300});
vec.push_back(example{300});
return 0;
}

Recursive constructors in C++

I build a class for containing vectors with no default constructor. Specifically:
template<typename T>
struct MyVector
{
public:
int GetN(void)
{
return n;
}
MyVector(int n1)
{
n=n1;
ListElt = new T[n1];
}
~MyVector()
{
delete [] ListElt;
}
// some other irrelevant to the question code
private:
int n;
T *ListElt;
};
Now I want to build a class derived from it that contains one integer and a vector.
The code that works is the following:
struct EquivInfo {
public:
EquivInfo(int inpOrbit, MyVector<int> &inpMat)
{
iOrbit=inpOrbit;
eVect=new MyVector<int>(inpMat.getN());
// some code for copying the vector in place.
}
~EquivInfo()
{
delete eVect;
}
private:
int iOrbit;
MyVector<int> *eVect;
};
Is there a way to avoid the use of the pointer for the vector?
The problem is that if I remove the pointer then there is a call to a constructor of the kind MyVector(). I do not understand why. There should be a way to have a constructor for EquivInfo that calls a precise constructor for MyVector
I could add a constructor MyVector(), i.e. a default constructor that set the vector to something trivial. But precisely, I want to avoid such kind of constructors so that all vectors are well defined and the code is clean. The use of the pointer allows me to have a reasonable situation but I wonder if there is a clean way to avoid it.
Use member initializer list:
class EquivInfo {
public:
EquivInfo(int inpOrbit, MyVector<int> &inpMat)
: eVect(inpMat.getN())
, iOrbit(inpOrbit) {
// some code for copying the vector in place.
}
// ....
MyVector<int> eVect;
}

c++ Segmentation fault in destructor child class

hi i am delevop a multicontainner using templates, but i am getting a segmentation fault from the child class destructor, here is the code:
#include <algorithm>
#include <map>
#include <iostream>
class BaseType{
public:
virtual ~BaseType(){}
virtual BaseType * clone() const =0;
};
template<typename T>
class DataType : public BaseType
{
public:
DataType(const T & aValueData = T()):mValue(aValueData) {
// new DataType<T>(*this)
}
~DataType(){
}
BaseType * clone() const
{
return new DataType<T>(*this);
}
T mValue;
};
class MValueData
{
public:
template<typename T>
MValueData(T const & aAnyValue = T()):mTypeData(0),isDelete(false)
{
std::cout<<"Object Address before create object: "<<mTypeData<<std::endl;
mTypeData=new DataType<T>(aAnyValue);
std::cout<<"Object Address after create object"<<mTypeData<<std::endl;
}
~MValueData(){
std::cout<<"Object Address "<<mTypeData<<std::endl;
delete mTypeData;
mTypeData=0;
}
MValueData()
{
mTypeData=0;
}
template<typename T>
MValueData(const MValueData & aCopy)
{
mTypeData= new DataType<T>();
*mTypeData=aCopy.mTypeData;
}
template<typename T>
const MValueData & operator=(const MValueData & aCopy)
{
mTypeData= new DataType<T>();
*mTypeData=aCopy.mTypeData;
//MValueData(aCopia).swap(*this);
}
void swap(MValueData& other) {
std::swap(this->mTypeData, other.mTypeData);
}
template <typename T>
T& get()
{
return dynamic_cast<DataType<T>&>(*this->mTypeData).mValue;
}
bool operator <(const MValueData &rhs) const {
return (mTypeData<rhs.mTypeData);
}
template<typename T>
void setValue(T const & anyValue=T())
{
mTypeData= new DataType<T>(anyValue);
}
BaseType *mTypeData;
private:
bool isDelete;
};
int main()
{
MValueData aAnyType_1(0.22);
aAnyType_1.get<double>();
MValueData aAnyType_2(false);
std::map<MValueData , MValueData&> mMapa;
mMapa.insert(std::pair<MValueData , MValueData&>(aAnyType_1,aAnyType_2));
// mMapa.find(aAnyType_1);
return 0;
}
I am using GDB to determinate the bug but i cannot see proper way to fix, the segmentacion stop when i comment this line:
~MValueData(){
// if(mTypeData) delete mTypeData;
}
Only then it run propperly, but it seems that i am creating a memory leak.
Updated:std::map create copys of the object that i insert into, the object is destroyed twice, one when exit the main function and another when std::map is destroying it self,
any hint?
thx in advance!
This segmentation fault might appear to be in the destructor, but it is a problem in your copy constructor. Lets take a simple example, I have a class which stores a pointer. Then I copy this pointer value like you are doing: I will have two pointers to the same memory location. Now I delete one of these objects, thus deleting the value at the pointer. The second object will have a pointer to invalid memory, and when this tries to delete the memory you get a segmentation fault.
How to fix this:
Well there are a few ways actually. Firstly, you need to decide whether you want deep copying of the pointers or not. If you do, write a deep copy of the memory the pointer points too. If not I reocmmend using shared_ptr to avoid these sorts of problems.
Your copy constructor is broken. You are not cloning the object, but only the pointer. Once an object is copied, the two copies will try to delete the same real object in memory in the destructor and that will cause a crash. You need to figure out who should own the object and whether you want it cloned or shared among the different instances of the MValueData object. Then act accordingly to fix the issue.
Your copy constructor is not correct.
It only copies the pointer not the object.
The two objects copied with the copy constructor will try to delete the same object in their destructor.

How to implement std::move() when dealing with C library objects

Lets say we have the following code
class Image
{
public:
Image(const std::string & path)
{
pBitmap_ = FreeImage_Load( imageFormat, pathname.c_str() );
}
~Image()
{
FreeImage_Unload(pBitmap_);
}
private:
FIBITMAP * pBitmap_;
};
How would Image(Image && rhs) be implemented?
after moving the dtor is still called on rhs, which will not give the intended effect?
I suppose something like
Image::Image( Image && rhs )
{
pBitmap_ = std::move(rhs.pBitmap_);
rhs.pBitmap_ = nullptr;
}
and then checking against null in the dtor should do the trick, but is there a better way?
The solution is to not do it yourself, but use the library facilities of the language:
struct FiBitmapDeleter {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
class Image {
private:
std::unique_ptr<FIBITMAP, FiBitmapDeleter> pBitmap_;
};
Now you don't need to write destructor, move constructor, or move assignment operator. Also your class automatically has its copy constructor and copy assignment operator deleted, so you don't need to worry about those either, completing the Rule of Five.
An alternative is to specialize default_delete, meaning that you don't need to supply the deleter type to unique_ptr:
namespace std {
template<> struct default_delete<FIBITMAP> {
void operator()(FIBITMAP *pBitmap) { FreeImage_Unload(pBitmap); }
};
}
std::unique_ptr<FIBITMAP> pBitmap_;
This has global effects, so you should only do it if you're confident that yours is the only code in the program that might perform this specialization.

Implementing Smart Pointer - storing template class in vector

I'm having trouble storing instances of my smart pointer into a container. Here is the code for the pointer.
#include "std_lib_facilities.h"
template <class T>
class counted_ptr{
private:
T* pointer;
int* count;
public:
counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {} // default constructor
explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
~counted_ptr()
{
--*count;
if(!*count) {
delete pointer;
delete count;
}
}
counted_ptr& operator=(const counted_ptr& p) // copy assignment
{
pointer = p.pointer;
count = p.count;
++*count;
return *this;
}
T* operator->() const{ return pointer; }
T& operator*() const { return *pointer; }
int& operator[](int index) { return pointer[index]; }
int Get_count() const { return *count; } // public accessor for count
};
int main()
{
counted_ptr<double>one;
counted_ptr<double>two(one);
one = new double(5);
vector<counted_ptr<double> >test;
}
In int main(), the vector<counted_ptr<double> > line does compile. When I first tried it with just vector<counted_ptr<double> > it didn't compile (probably because it was lacking parameters.) However, when I try to use push_back such as
test.push_back(one);
I get a compiler error that opens up vector.tcc with the specific error saying that
no matching function for call to `counted_ptr<double>::counted_ptr(const counted_ptr<double>&)'|
I'm guessing that push_back can't find a counted_ptr, but I'm really not sure. Any
help is appreciated, thanks.
Edit: However, this works. test[0] = one; I guess the semantics of push_back are what is restricting it.
You may want to try this:
test.push_back(counted_ptr<double>(one));
You copy constructor is explicit which means that the compiler won't implicitly invoke it.
Personally, I would make the raw pointer constructor explicit and the copy ctor not explicit. That would be closer to usual behavior.
EDIT: I also recommend that you implement a swap method. It makes assignment absolutely trivial. You end up with something like this:
counted_ptr &operator=(const counted_ptr &rhs) {
counted_ptr(rhs).swap(*this);
return *this;
}
This also has the benefit of all of the accounting happening in constructors/destructors which is a lot simpler to manage :-).
Your assignment operator is wrong.
What happened to the object it was pointing at?
What happens if you are assigning to yourself or the same internal object?
counted_ptr& operator=(const counted_ptr& p) // copy assignment
{
if (&p != this)
{
--*count;
if ((*count) == 0) // Much more readable than !*count
{
delete pointer;
delete count;
}
pointer = p.pointer;
count = p.count;
++*count;
}
return *this;
}
Note: Writing your own smart pointer is not a good idea.
They are not as trivial to write as you think.
Note: This is the first thing I spotted. There could be more, and I am not sure this is 100% correct.
In fact I would change the assignment operator to use copy/swap idium.
counted_ptr& operator=(const counted_ptr& p) // copy assignment
{
counted_ptr<T> tmp(p); // increment counter on p
swap(tmp.pointer, pointer);
swap(tmp.count count);
return *this;
// tmp goes out of scope and thus the
// destructor gets called and what was in this
// object is now destroyed correctly.
}
// It may even be worth writing your own swap operator.
// Make sure you declare it as no-throw and grantee it.