What is the best way to deal with the following situation?
Suppose that I have something that should behave like this
class Foo
{
public:
Foo(Bar& bar):m_bar(bar){}
private:
Bar& m_bar;
};
Foo:s must have a valid reference to Bar:s. Also different Foo:s needs different or the same Bar:s.
I want to store Foo:s in an array. However, since Foo will require a non-default constructor, it will not work.
I could create an array of pointers to Foo:s, but then I need to call new and delete for each object in that array.
I could define Foo like this instead
class Foo
{
public:
void init(Bar& bar)
{
m_bar=&bar;
}
private:
Bar* m_bar;
};
, but then it is possible to create uninitialized Foo:s.
What about some sort of placement new?
You could use pointers still but instead of using raw pointers use unique_ptrs. These are available in c++11, but if you are using an older compiler you could use the boost implementation.
For example
class Foo
{
public:
Foo(unique_ptr<Bar> bar):m_pBar(bar){}
private:
unique_ptr<Bar> m_pBar;
};
This way you don't have to worry about calling delete on your Bar objects as they are deleted once there are no more references to them.
Then you can use Foo like this
unique_ptr<Bar> pBar(new Bar());
Foo(pBar);
EDIT: Changed to use unique_ptr instead of shared_ptr and added example usage
First, sorry for my first answer I got the question wrong. Here is a better solution I hope: you can create a vector
of elements without default constructor like this:
#include <iostream>
#include <vector>
using namespace std;
class Foo
{
public:
Foo(int& bar): m_pBar(bar)
{ }
Foo& operator=(const Foo& other)
{ m_pBar = other.m_pBar; }
int Get()
{ return m_pBar; }
private:
int& m_pBar;
};
int main(int argc, char** argv)
{
int test[10] = { 0 };
vector<Foo> vect;
for (int& i: test)
vect.emplace_back(i);
test[0] = 1;
cout << vect[0].Get() << endl;
return 0;
}
Finally I implemented a custom container with the following constructor:
template<class T>
template<class U,class V>
Array<T>::Array(unsigned int n,U source_iterator,const V& source_resource):memory(n*sizeof(T))
{
data=(T*)memory.pointerGet();
unsigned int k;
try
{
for(k=0;k<n;k++)
{
new(data+k)T(*source_iterator,source_resource);
++source_iterator;
}
}
catch(...)
{
while(k>0)
{
k--;
data[k].~T();
}
throw;
}
length=n;
capacity=n;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.