I can't remember what it is called, but I know i can do it in Java.
Suppose I have the following:
class Foo
{
public:
Foo() {};
void bar() {};
};
I want to do this:
int main() {
(new Foo).bar();
}
But it doesn't seem to work. Is there a similar way to do this without having to do:
int main() {
Foo foobar;
foobar.bar();
}
new dynamically-allocates memory and returns a pointer. Class members are obtained using the indirection operator ->. I don't think this is what you're looking for as you run the risk of causing a memory leak. Simply calling the constructor of Foo allows us to do what we want:
Foo().bar();
By calling the constructor of Foo, we create a temporary object off of which we can obtain its data members. This is preferred over pointers as we don't have to deal with memory leaks and deletion of the pointer.
You can say (new Foo)->bar();. That works but is absolutely idiotic. The correct thing is this:
int main()
{
Foo x;
x.bar();
}
Or, if you don't want the local variable: Foo().bar();. But now that's questionable, since if you don't need Foo to be stateful, then you probably don't need a class at all. Just make bar a free function (something that doesn't exist in Java):
void bar();
int main()
{
bar();
}
Yes, Foo().bar();. No need to use new like in Java.
Related
I need to use a library which defined a register_cb function taking a void* as it's parameter:
void register_cb(void* data, ...) {
}
Now I wish to pass it some data which I'm not storing on stack, easy way to illustrate is to call this from another function:
void my_processor_fn() {
Foo foo;
register_cb(&foo); //Invalid as foo will go out of scope.
}
So I can use the heap:
void my_processor_fn() {
Foo* foo = new Foo();
register_cb(foo); //Valid but I'll have to call delete to avoid memleak
}
And I can also use smart pointers:
void my_processor_fn() {
std::unique_ptr<Foo> foo(new Foo());
register_cb(&foo); //Invalid, as unique_ptr will go out of scope and will delete foo.
}
How can I leverage smart pointers in these situation when I need to pass void* to a library function, and later the library will call my callback function with the address I have passed into register_cb?
Usually you can extend the lifetime of such objects by putting them in a class. Something like:
class MyProcess {
public:
MyProcess() : data_{std::make_unique<Foo>()} {}
void my_processor_fn() {
register_cb(data_.get());
}
private:
std::unique_ptr<Foo> data_;
};
If you make this object then use it, everything will stay alive for you:
int main() {
MyProcess my_process{};
my_process.my_processor_fn();
// pressumably some spinner that keeps the process alive while callbacks happen.
}
I realize that similar questions have been asked elsewhere, but I couldn't find an answer that's a good fit for my function signatures.
Consider this typical pair of C functions:
int initFoo(Options options, Foo* foo);
void freeFoo(Foo* foo);
initFoo takes some options and a pointer to an uninitialized Foo struct. It initializes this struct and returns a result code that indicates whether the initialization was successful. freeFoo frees an initialized Foo struct.
Now assume I want to use these C functions in my C++ code. I want to use RAII, so I need to construct a unique_ptr<Foo> that will automatically call freeFoo on destruction. The best approach I could come up with is this:
template<typename T>
using lambda_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
lambda_unique_ptr<Foo> createFoo(Options options) {
Foo* foo = new Foo();
const int resultCode = initFoo(options, foo);
if (resultCode != 0) throw ...;
return lambda_unique_ptr<Foo>(foo, [](Foo* foo) {
freeFoo(foo);
delete foo;
});
}
I'm certain that there must be a more elegant solution. Ideally, something more functional that doesn't require so many individual steps. What I find particularly ugly is the necessity to explicitly allocate the Foo struct on the heap, then explicitly free and delete it in two steps. Any ideas?
Can't you just wrap Foo in a class?
struct FooWrap {
Foo foo;
explicit FooWrap(Options options) {
if (initFoo(options, &this->foo))
throw ...;
}
~FooWrap() {
freeFoo(&this->foo);
}
// XXX: either implement or disable assignment and copy construction
};
Now you can choose whether to just define FooWrap x(42); as an automatic variable or whether to allocate it dynamically with new.
Having this:
class Foo
{
public:
void destroy() { delete this; }
public:
// Stuff here...
};
int main(int argc, char *argv[])
{
Foo* foo = new Foo;
// Option 1
delete foo;
// Option 2:
foo->destroy();
return 0;
}
Is Option 1 and Option 2 the same operation? Is it a 'correct' way for destroying objects? Why/Why not?
Thank you so much,
Yes, the two are equivalent in this case.
But you should definitely prefer Option 1. delete this is very easy to get wrong, violates various design principles, and in this instance is completely pointless.
Such destruction schemes (a member function deleting the this pointer) are the common solution when implementing classes that allow instances only on the heap
class Foo
{
~Foo(); // private destructor - won't allow objects on the stack
public:
void destroy() { delete this; }
public:
// Stuff here...
};
In the above example, the destructor can't be called, so you can't say
delete FooInstance;
and your only option to avoid memory leaks is to have a destroy function:
FooInstance->destroy();
Apart from that I haven't found any real world cases where such a destruction function is/has to be used.
As others said, it's not common and discouraged. A usually reliable source says that you can technically do it if you strictly follow a few rules; in particular, do not access freed memory or class members after the delete: http://www.parashift.com/c++-faq/delete-this.html.
Option 1 is the recommended way to delete a class object.
class Foo
{
public:
~Foo()
{
//define destructor if you have any pointer in your class
}
public:
// Stuff here...
};
int main()
{
Foo* foo = new Foo;
// By deleting foo it will call its destructor
delete foo;
}
For Option 2
The C++ FAQ Lite has a entry specifically for this
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15
As long as you're careful, it's OK for an object to commit suicide (delete this).
foo.h
#include <iostream>
#include <memory>
class Bar
{
public:
Bar() {};
~Bar() {};
void print() {
std::cout << "hello";
}
};
class Foo
{
public:
Foo();
~Foo();
void use() {
pteste->print();
}
private:
std::unique_ptr<Bar> pteste;
};
#endif
main.cpp
#include <memory>
#include "foo.h"
int main(int argc, char *argv[])
{
Foo s;
s.use();
return 0;
}
Why and how does it works "normally"?
Thanks
EDIT: I understand about the incomplete types, but what happens when I can use unique_ptr without using new and why works
EDIT2: Organized the code better for my question
Short answer: It doesn't work.
This reference says that the default constructor of std::unique_ptr creates an empty unique pointer, meaning it has no associated object.
The reason why this code prints hello is because this statement
std::cout << "hello";
doesn't need anything of Bar. It could just as well be a static method. Maybe the compiler inlines the function and replaces s.use() with the std::cout-statement. But even if it does call the method, you won't notice any errors since it doesn't access the memory of Bar at all.
Make a slight change to your class and you will see what I mean:
class Bar
{
public:
Bar() : data(10) {};
~Bar() {};
void print() {
std::cout << "hello, data is: " << data;
}
int data;
};
Now, print accesses invalid memory, because you never called new (or even better: make_unique). It may even work and print something to the console, but the output of data will be garbage. If you're lucky, the application will crash.
Another reason why it appears to work (thanks Stas):
std::unique_ptr defines operator->, which simply returns the contained pointer, but does not check if the pointer points to valid memory. So pteste-> won't throw an exception.
Yes, this code will "normally" print "hello" to console and it is not related to unique_ptr. You can replace std::unique_ptr<Bar> pteste with Bar* pteste in Bar and get the same result.
Consider how pteste->print() is called.
You can think about Bar::print() as a free function that take pointer to Bar object:
void print(Bar* this) {
std::cout << "hello";
}
See, pointer passed to print(Bar*) is never touched, so you can theoretically pass whatever you want (null, garbage etc.) and it will print "hello" to console.
It works because
std::unique_ptr<Bar> pteste;
is a pointer declaration to the instance, it does not instantiate the pointer so it does not need to know at this point the details about Bar (e.g. ctor).
In the case of
Bar pteste
in order for pteste to be constructed it will need the know definition but since Bar is only forward declared it will give an error.
All pointers are implemented the same way. Even though you have pointers to different types, all are the size of an int usually. So the compiler does not need to know about the type of the pointee when it compiles your code. Now if you were to dereference that pointer that would be a different story. Even if you would initialize your unique_ptr it would need to know the type, since new needs to see the constructor.
Is this safe? I'm not using any virtual functions in my actual implementation, but I'm tempted to believe that even if I was, it would still be safe.
class Foo
{
Foo()
{
// initialize things
}
Foo( int )
{
new ( this ) Foo();
}
}
By the time you enter the open curly brace of the Foo(int) constructor, all class members have had their constructor called. If you then force a call to another constructor with placement new, you're overwriting the current state of the class. This basically means all members have their constructors called twice - if something does new in its constructor, you leak that content, and you will really, really mess things up! You're effectively constructing two objects, and the destructors for the members of the first object are never called, since the second object overwrites the memory of the first object.
In other words it's BAD! Don't do it!!
The most common workaround is to use some kind of initialisation function, and call that from both constructors. This won't let you initialize const members and others that must be in the initializer list, though.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3
One worry I have is if Foo uses multiple inheritance you'll need to cast the this pointer to the most base class first. Othewise if the the this is offset (sometimes happens in multiple inheritance) it'll construct at the wrong address.
You wouldn't be safe if you extended another class and that class had a destructor, for example
class Foo
{
int* a;
public:
Foo():a(new int)
{
}
~Foo(){delete a;}
}
class Bar:public Foo
{
Bar()
{
// initialize things
}
Bar( int )
{
new ( this ) Foo();
}
}
First Bar(int) calls Foo(), then it calls Bar() which also calls Foo(). The second time Foo() is called, it overwrites the pointer set up by the first call to Foo(), and the allocated memory is leaked.
The key problem here is that constructors are special - when you write a construct that calls a constructor (for example use new keyword to create an object) not only the constructor body is executed, instead the whole chain of objects is constructed first.
So when you use placement-new syntax to run another constructor first C++ automagically reruns all the base class object constructors and all the member variables constructors and only then the other constructor body is invoked. Sometimes you'll be okay, but many times you will run into unexpected behavior.
It looks like the best solution to this problem is to just create a different function to do the initialization:
class Foo
{
inline void nullify()
{
// initialize things
}
Foo()
{
nullify();
}
Foo( int )
{
nullify();
}
}
As others said, is a bad idea, and as a possible destructive case: what if you do
class Foo
{
Foo()
{
// initialize things
}
Foo( int bar )
{
new ( this ) Foo(bar);
}
}
welcome no the land of infinite recursion.