I have the following setup:
class Foo {
public:
Foo() {}
vector<BigObject*> mPointers;
};
class Bar {
public:
Foo *exposeSomeFoo() { return &mFoos[42]; }
private:
vector<Foo> mFoos;
vector<BigObject> mMemoryManaged;
};
I'm basically trying to make sure that at no point in my code will someone accidentally use a Foo for which the Bar it was exposed from has gone out of scope.
But this is obviously problematic. If I expose pointers to Foo like above, they become invalid once Bar goes out of scope. If I instead use Foo exposeSomeFoo(), the mPointers will become invalid once Bar goes out of scope, too - and returning copies seems like a bad idea if mPointers has a lot of elements!
I've tried solving this by making a private copy constructor:
class Foo {
public:
Foo() {}
vector<BigObject*> mPointers;
private:
Foo(const Foo&);
};
But then I get errors when I try to insert a Foo into mFoos from within Bar.
There must be a paradigm that allows full memory safety while still allowing me to expose functionality like this. How can I expose, to code elsewhere, a composite object from Bar whose memory is managed specifically by Bar or at least in the compilation unit itself?
If you want to make sure that all of your objects can share resources, such that the resource is alive as long as all of the objects are, just use std::shared_ptr everywhere:
class Foo {
public:
Foo() {}
vector<shared_ptr<BigObject>> mPointers;
};
class Bar {
public:
shared_ptr<Foo> exposeSomeFoo() { return mFoos[42]; }
private:
vector<shared_ptr<Foo>> mFoos;
vector<shared_ptr<BigObject>> mMemoryManaged;
};
That way, a caller can hold onto bar.exposeSomeFoo() without worry - the caller now shares ownsership of it, sot his will be perfectly safe.
Actually, I ended up doing something like this:
class Foo {
public:
Foo(shared_ptr<vector<BigObject> > bigObjects) : mBigObjects(bigObjects) {
}
private:
vector<BigObject*> mPointers;
shared_ptr<vector<BigObject> > mBigObjects;
};
class Bar {
public:
Bar() {
mBigObjects = shared_ptr<vector<BigObject> >(new vector<BigObject>);
for (int i = 0; i < 100; i++)
mBigObjects->push_back(BigObject());
for (int i = 0; i < 100; i++)
mFoos.push_back(Foo(mBigObjects));
}
Foo exposeSomeFoo() { return mFoos[42]; }
private:
shared_ptr<vector<BigObject> > mBigObjects;
vector<Foo> mFoos;
};
I think this is the behavior I want: only when all instances of both Foo and Bar are destroyed, is the vector with BigObjects actually destroyed. Can someone double-check that this is safe and good practice? Thanks!
Related
I am trying to code two classes FooFactory and Foo. FooFactory initializes an object ToolBox in the constructor and stores it in a unique_ptr as I want that to be cleaned after the factory is destructed. All the instances of Foo should be able to use ToolBox so I am passing ptr to ToolBox object in the constructor of Foo and storing it as bare ptr.
I am new to c++ development so, my questions in the light of general suggestion I heard :
avoid raw pointers when possible
Is the usage of bare ptr to store the tool_box object that Foo doesn't own fine in this case? or Can I do better using smart_ptr?
Is the pattern of passing the ptr to ToolBox from the FooFactory class to every new object the correct or is there something better I can do?
Pseudo-code for my classes:
class FooFactory {
public:
FooFactory() {
tool_box_.reset(new ToolBox());
}
std::unique_ptr<Foo> NewFoo() {
std::unique_ptr<Foo> foo(new Foo(tool_box_.get());
return foo;
}
std::unique_ptr<ToolBox> tool_box_;
}
class Foo {
public:
Foo(ToolBox* tool_box) {
tool_box_ = tool_box;
}
private:
// Not Owned
ToolBox* tool_box;
}
A factory would normally never control the lifetime of an object. It should hand out an appropriate pointer, preferably a std::unique_ptr and the caller determines it's lifetime.
#include <string>
#include <iostream>
#include <memory>
class Box
{
public:
Box() {}
};
class Foo
{
public:
Foo(std::shared_ptr<Box> &box)
: m_box(box)
{
}
virtual ~Foo(){}
void print()
{
std::cout << "Hello World" << std::endl;
}
protected:
Box *getBox()
{
return m_box.get();
}
private:
std::shared_ptr<Box> m_box;
};
class FooFactory
{
public:
FooFactory()
{
m_box = std:make_shared<Box>();
}
std::unique_ptr<Foo> CreateFoo()
{
return std::make_unique<Foo>(m_box);
}
private:
std::shared_ptr<Box> m_box;
};
int main()
{
FooFactory factory;
std::unique_ptr<Foo> foo = factory.CreateFoo();
foo->print();
return 0;
}
One way to store a non-owning "pointer" to an object (while coupling the class with that object) would be to store a reference (or perhaps a const reference) instead of a pointer.
In my experience, the constraint of needing to initialize the class with that reference helps hierarchical design and simplifies lifetime management.
I'm sure there's a standard way to solve this problem, but I can't find it.
I have a Processor class which manages the lifespans of all objects. A Foo may be assigned to a Bar occasionally. But Bar needs to know when Foo is no longer available (has been removed by the Processor). What is the right way to achieve this?
class Processor {
private:
vector<unique_ptr<Foo>> foos;
vector<unique_ptr<Bar>> bars;
};
class Bar {
public:
void AssignFoo(Foo* foo){ cur_foo = foo; }
private:
Foo* cur_foo = nullptr;
};
One option I can think of is to have a map in Processor which keeps track of the assignments, and have a function RemoveFoo in Bar but I'm wondering if there's any other way.
One way to do it is using std::shared_ptr and std::weak_ptr:
class Processor {
private:
vector<std::shared_ptr<Foo>> foos;
vector<std::unique_ptr<Bar>> bars;
};
class Bar {
public:
void AssignFoo(const std::weak_ptr<Foo>& foo){ cur_foo = foo; }
private:
bool FooIsValid() const {
return !cur_foo.expired();
}
std::weak_ptr<Foo> cur_foo;
};
EDIT: tried earlier to use unique_ptr and raw pointers but it turn out wrong from the beginning so I removed it.
I’m building an Arduino project and would like to build a reusable library. However what I can easily do in C# is eluding me in the C/C++ syntax the Arduino firmware uses.
I would like to instantiate a global instance of class Foo that also contains a structure Bar which will be used in the constructor of Foo so I can take advantage of encapsulation, e.g. if I need to add a new element to Bar I can do so easily.
C#
Foo myFoo;
void BobBobLaw()
{
Bar myBar = new Bar();
myBar.A = 1;
myBar.B = 2;
myBar.C = 3;
myFoo = new Foo(myBar);
myFoo.DoSomething();
}
How can I accomplish something similar for the Arduino platform? BTW, I chose to use a struct instead of a class for Bar because that information is immutable and should be private. I’m not sure if this is the correct choice, but I read a few posts that said this is the “preferred” way to do things.
As #Lightness Races in Orbit mentioned in the comments. You can declare pointer to a Foo in global context and in the setUp function you can initialize in the global pointer with new'd object of Foo.
Using struct doesn't make it Bar immutable. In C++, structure is equivalent to a class just with an exception of default access specifier being public. One way to make Bar immutable is to make members private and make sure only the constructor can modify it.
Following example gives one such example with immutable Bar as member of Foo class. I hope you find it useful.
#include <iostream>
#include <string>
class Bar {
private:
int A,B,C;
public:
Bar(int a,int b, int c):A(a),B(b),C(c){};
int getA() const { return A; }
int getB() const { return B; }
int getC() const { return C; }
};
class Foo {
private:
Bar *mBar;
public:
Foo(Bar barInstance) {
mBar = new Bar(barInstance.getA(),barInstance.getB(),barInstance.getC());
}
void DoSomething() {
std::cout<<"Doing something";
}
};
Foo *fooPointer;
void setUpArduino() {
Bar myBar(1,2,3);
fooPointer = new Foo(myBar);
fooPointer->DoSomething();
}
int main() {
setUpArduino();
}
Is there any way in C++ to create class within a function, and then prevent it from destructing?
like
class someclass {
public:
int x;
someclass() { x = 0; };
}
someclass::x;
and then somewhere
someclass * somefunction()
{
someclass somecl ();
return &somecl;
}
So we call function 'somefunction' and get pointer to class for later using. I need it to exist as long as program runs/it destructed by other function. Is there any way to do it without storing it inside arrays or vectors?
I'm not sure if what you're looking for is a way to define an object once and only once, returning a pointer to the same object each time, or to create a factory function that returns the a newly constructed object each time. If it's the second, look at previous answers. If it's the first, check out static variables. As an example, you could write
someclass * somefunction()
{
static someclass somecl ();
return &somecl;
}
This ensures that somecl is only defined once, when the function is initially run and that it will be alive until your program exits. (For a more precise description of the order of cleanup for static variables, see here.)
Yes, you have to allocate the memory on the heap and then delete the memory when you are done.
someclass * somefunction()
{
return new someclass();
}
int main()
{
someclass * myclass = somefunction();
// do stuff with myclass
delete myclass;
return 0;
}
someclass * somefunction()
{
return new somecl ();
}
You were very close :)
You could create it on the heap rather than the stack:
someclass * somefunction()
{
return new someclass();
}
You may also want to consider returning it in a smart pointer, to explicitly transfer ownership and control its lifetime.
I'm not exactly sure what you are driving at, I can imagine two different use cases where you would want to make a class indestructible.
Case 1: Singleton
The idiomatic way to do this, is to use a static instance of the class that's declared within an accessor function:
class Foo {
public:
static Foo& globalFoo();
private:
Foo() {};
~Foo() {};
};
Foo& Foo::globalFoo() {
static Foo myFoo;
return myFoo;
}
int main() {
Foo& myFoo = Foo::globalFoo();
}
That way, it is impossible for other code to either construct or destruct any instance of Foo, it can only use the one instance that's provided by the globalFoo() function.
Case 2: Wrapped allocation/deallocation
If you just want to force allocation/deallocation to happen via certain static functions, you only need to make both the constructor and the destructor private (just as in the singleton case), and add static functions to the interface for allocation/deallocation:
class Foo {
public:
static Foo* makeFoo();
static void destroyFoo(Foo* aFoo);
private:
Foo() {};
~Foo() {};
};
Foo* Foo::makeFoo() {
return new Foo();
}
void Foo::destroyFoo(Foo* aFoo) {
delete aFoo;
}
int main() {
Foo* myFoo = Foo::makeFoo();
Foo::destroyFoo(myFoo);
}
The following code fails to compile in Visual C++ 11 with this error:
1>c:\users\tony\documents\visual studio 11\projects\cpp11_ex1\cpp11_ex1\main.cpp(52): error C2440: '' : cannot convert from 'Foo *const ' to 'std::weak_ptr<_Ty>'
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( weak_ptr<Foo> foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
weak_ptr<Foo> _foo;
};
class Foo
{
public:
Foo() : _bar() { _bar = make_shared<Bar>( weak_ptr<Foo>(this) ); printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}
It seems that I can't create a weak_ptr from a raw this pointer. This causes an interesting series of problems.
Since I am attempting this in Foo's ctor, Foo's reference count is 0 (i.e. the make_shared<> in main hasn't returned yet).
I've discovered that I can create weak_ptrs from shared_ptrs... But if I change Bar ctor to take a shared_ptr, I the act of calling Bar's constructor ends up destroying Foo! (Since Foo's reference count is still 0, creating (and then destroying) a shared_ptr to Foo via a call to Bar's ctor ).
All I really want to do is create Foo, have Foo create and own a Bar, but have Bar have a weak reference back to Foo. I really don't want to be forced into 2 part initialization here!
boost::weak_ptr<T> is for storing, not for using.
You want to pass boost::shared_ptr objects, and then store them in the boost::weak_ptr objects (usually private).
struct Foo {
Foo(const boost::shared_ptr<int> &data) : weak_data(data) {}
boost::shared_ptr<int> getData() {
boost::shared_ptr<int> data = weak_data.lock();
if (!data)
throw std::runtime_error("data is no longer valid");
return data;
}
private:
boost::weak_ptr<int> weak_data;
};
Whether you throw or pass back and empty shared_ptr<T> is up to you. If you cannot lock the object though, you shouldn't be passing it around anymore. It really isn't valid at that point.
That being said, you may want to refrain from creating a shared pointer in that manner. It isn't clear from your example if you need this design. If you can redesign it in a way like Mooing Duck suggested you will be better off, in all honesty.
From similar experiences when I needed circular dependencies like this, it probably is not a simple construction scenario. I would look at a two part constructor (static named constructor, or builder perhaps) to manage creating the two objects and ensuring that their references are valid.
Here is a quick example of a simple named constructor.
class Foo;
// Likely that this should be a child class of Foo
class Bar {
private:
friend class Foo;
Bar(const boost::shared_ptr<Foo> &foo) : weak_foo(foo) {}
weak_ptr<Foo> weak_foo;
};
class Foo {
public:
static boost::shared_ptr<Foo> CreateFoo() {
boost::shared_ptr<Foo> foo = boost::shared_ptr<Foo>(new Foo);
foo.bar = boost::make_shared<Bar>(foo);
return foo;
}
private:
Foo() {}
boost::shared_ptr<Bar> bar;
};
Here you control the invariant that your foo and bar variables are created correctly.
Since Foo will be pointed at by a shared_ptr, and Bar will always be owned by a shared_pointer of Bar, then if Bar exists, Foo exists. Ergo, you don't need a smart pointer in Bar. (If I understand the problem correctly)
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( Foo* foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
Foo* _foo;
};
class Foo
{
public:
Foo() : _bar(new Bar(this)) { printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}
It is not possible to have a weak pointer in the absence of strong pointers to the same object, by definition. When the last strong pointer goes away, all the weak pointers turn null. That's all the weak pointers do.
Write your own function that returns a shared ptr to Foo (a Foo factory), and initialize the weak ptr in Bar from that pointer.