Is there a way to force a class to be instantiated on the stack or at least prevent it to be global in C++?
I want to prevent global instantiation because the constructor calls C APIs that need previous initialization. AFAIK there is no way to control the construction order of global objects.
Edit: The application targets an embedded device for which dynamic memory allocation is also prohibited. The only possible solution for the user to instanciate the class is either on the stack or through a placement new operator.
Edit2: My class is part of a library which depends on other external libraries (from which come the C APIs). I can't modify those libraries and I can't control the way libraries are initialized in the final application, that's why I am looking for a way to restrict how the class could be used.
Instead of placing somewhat arbitrary restrictions on objects of your class I'd rather make the calls to the C API safe by wrapping them into a class. The constructor of that class would do the initialization and the destructor would release acquired resources.
Then you can require this class as an argument to your class and initialization is always going to work out.
The technique used for the wrapper is called RAII and you can read more about it in this SO question and this wiki page. It originally was meant to combine encapsulate resource initialization and release into objects, but can also be used for a variety of other things.
Half an answer:
To prevent heap allocation (so only allow stack allocation) override operator new and make it private.
void* operator new( size_t size );
EDIT: Others have said just document the limitations, and I kind of agree, nevertheless and just for the hell of it: No Heap allocation, no global allocation, APIs initialised (not quite in the constructor but I would argue still good enough):
class Boogy
{
public:
static Boogy* GetBoogy()
{
// here, we intilialise the APIs before calling
// DoAPIStuffThatRequiresInitialisationFirst()
InitAPIs();
Boogy* ptr = new Boogy();
ptr->DoAPIStuffThatRequiresInitialisationFirst();
return ptr;
}
// a public operator delete, so people can "delete" what we give them
void operator delete( void* ptr )
{
// this function needs to manage marking array objects as allocated
// or not
}
private:
// operator new returns STACK allocated objects.
void* operator new( size_t size )
{
Boogy* ptr = &(m_Memory[0]);
// (this function also needs to manage marking objects as allocated
// or not)
return ptr;
}
void DoAPIStuffThatRequiresInitialisationFirst()
{
// move the stuff that requires initiaisation first
// from the ctor into HERE.
}
// Declare ALL ctors private so no uncontrolled allocation,
// on stack or HEAP, GLOBAL or otherwise,
Boogy(){}
// All Boogys are on the STACK.
static Boogy m_Memory[10];
};
I don't know if I'm proud or ashamed! :-)
You cannot, per se, prevent putting objects as globals. And I would argue you should not try: after all, why cannot build an object that initialize those libraries, instantiate it globally, and then instantiate your object globally ?
So, let me rephrase the question to drill down to its core:
How can I prevent my object from being constructed before some initialization work has been done ?
The response, in general, is: depends.
It all boils down at what the initialization work is, specifically:
is there a way to detect it has not been called yet ?
are there drawbacks to calling the initialization functions several times ?
For example, I can create the following initializer:
class Initializer {
public:
Initializer() { static bool _ = Init(); (void)_; }
protected:
// boilerplate to prevent slicing
Initializer(Initializer&&) = default;
Initializer(Initializer const&) = default;
Initializer& operator=(Initializer) = default;
private:
static bool Init();
}; // class Initializer
The first time this class is instantiated, it calls Init, and afterwards this is ignored (at the cost of a trivial comparison). Now, it's trivial to inherit (privately) from this class to ensure that by the time your constructor's initializer list or body is called the initialization required has been performed.
How should Init be implemented ?
Depends on what's possible and cheaper, either detecting the initialization is done or calling the initialization regardless.
And if the C API is so crappy you cannot actually do either ?
You're toast. Welcome documentation.
You can try using the Singleton pattern
Is there a way to force a class to be instantiated on the stack or at least prevent it to be global in C++?
Not really. You could make constructor private and create said object only using factory method, but nothing would really prevent you from using said method to create global variable.
If global variables were initialized before application enters "main", then you could throw exception from the constructor before "main" sets some flag. However, it is up to implementation to decide when initialize global variables. So, they could be initialized after application enters "main". I.e. that would be relying on undefined behavior, which isn't a good idea.
You could, in theory, attempt to walk the call stack and see from there it is called. However, compiler could inline constructor or several functions, and this will be non-portable, and walking call stack in C++ will be painful.
You could also manually check "this" pointer and attempt to guess where it is located. However, this will be non-portable hack specific to this particular compiler, OS and architecture.
So there is no good solution I can think of.
As a result, the best idea would be to change your program behavior, as others have already suggeste - make a singleton class that initializes your C api in constructor, deinitializes it in destructor, and request this class when necessary via factory method. This will be the most elegant solution to your problem.
Alternatively, you could attempt to document program behavior.
To allocate a class on the stack, you simply say
FooClass foo; // NOTE no parenthesis because it'd be parsed
// as a function declaration. It's a famous gotcha.
To allocate in on the heap, you say
std::unique_ptr<FooClass> foo(new FooClass()); //or
FooClass* foop = new FooClass(); // less safe
Your object will only be global if you declare it at program scope.
Related
I have a function call
void moveMeToThread(UnsafeStruct *ptr)
{
// do stuff with ptr
}
Now I want to move moveMeToThread to a different thread, so I do not want anyone creating an object of UnsafeStruct on the stack and I also want memory of all UnsafeStruct objects made on the heap to be freed automatically. Anyone have an elegant way to do this?
Sounds like you'd like to make a heap-only class. There are many ways to force this:
you might make private ctors (all of them!) and create a static create() function that returns a pointer (sometimes called named ctor)
you might make dtor private
The latter technically does not save you from placement new to a suitable memory block, but otherwise protects from sensible coding mistakes and is way more compatible with algorithms and containers. E.g. you can still copy such an object via copy ctor outside the class, which is not possible if you make all ctors private (which is a requirement for the first version).
You might do this:
template<typename T>
class HeapOnly
{
public:
T t;
operator T&() { return t; }
operator const T&() const { return t; }
private:
~HeapOnly();
};
void moveMeToThread(HeapOnly<UnsafeStruct> *ptr)
{ /* ... */ }
int main()
{
HeapOnly<UnsafeStruct> *ptr =
new HeapOnly<UnsafeStruct>{/* args to UnsafeStruct */};
moveToThread(ptr);
}
Small note: there's no such thing as (call/parameter) stack in the C++ standard. It only appears in ItaniumABI (and potentially in other ABIs). Standard says ASDV (automatic storage duration variables) for what's commonly referred to as 'on the stack', but nothing prevents an implementation to allocate the memory on the stack (as long as compiler can prove that the object's lifetime cannot extend the stack unroll - this works e.g. if it's allocated before static initialization). It might be completely unimportant in your case, but in security-related codes, where buffer overflow is important, you can't strictly enforce not having objects allocated from the same stack this way (and thus it's suggested to do a runtime check) - but you can still enforce that the object is allocated via new (or the given static member function).
I do not want anyone creating an object of UnsafeStruct on the stack.
I want to forbid it because if someone creates an object on the stack and sends it on the thread, it can cause a crash(dangling pointer)
Do you also want to prevent anybody from creating int variables on the stack? Because if somebody creates an int variable on the stack, and if they allow a reference or a pointer to it to outlive the stack frame that contains the variable, then their program could crash.
Seriously.
That problem is older than C++. That problem has existed since the very first edition of the C programming language. Every C and C++ programmer has to learn not to do that. Always have. Always will.
In some languages (e.g., Java, Python), No object of any kind can be allocated anywhere else except the garbage-collected heap. Variables can only hold references to objects, and dangling references are impossible. Programmers in those languages expect an assignment a=b to copy an object reference. That is, after the assignment, a and b both refer to the same object.
That's not the C++ way. C++ programmers expect that if some type T is publicly constructable, then they expect to be allowed to declare one wherever they want. And when they see a=b, they think of that assignment operator as copying a value. They expect that after the assignment, a and b still are two different objects that both have (in some sense) the same "value."
You will find more people saying positive things about your library if you design it to work in that same way.
I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it
I enjoy using the operators new and delete in C++ a lot but often have a problem calling delete later on in the program's code.
For example, in the following code:
class Foo {
public:
string *ace;
Foo();
~Foo();
};
Foo::Foo() {
ace = new string;
}
Foo::~Foo() {
delete ace;
}
void UI::ButtonPressed() { //Happens when an event is triggered
Foo *foo = new Foo;
ui->label = ace; //Set some text on the GUI
delete foo; //Calls the destructor, deleting "ace" and removing it from the GUI window
}
I can declare a new string but when I delete it, it removes the value from the GUI form because that string has now been deleted.
Is there a way for me to delete this allocated string somehow later on?
I don't want to declare it as a global variable and then delete it on the last line of the program's source code. I could just never call delete but from what I have been taught that's bad and results in memory leaks.
You should read about the RAII pattern. It is one of the most important concepts to know for a C++ programmer.
The basic idea is that the lifetime of a resource (a new'ed object, an HTTP connection, etc.) is tied to the lifetime of an object. This is necessary in order to write exception safe code.
In your case, the UI widget would make a copy of the object and free it in its own destructor. The calling code could then free its copy right away (in another destructor).
If you are using std::string for both ace and ui->label then you don't have to worry about the memory for foo->ace being deleted once the foo object goes out of scope.
A copy of the Right-Hand argument is made available to ui->label on an = (assignment operation). You can read more about it on the C++ std::string reference page for string::operator=.
Also, such problems can be avoided in full by using smart pointers, such as the ones provided by the boost library. Read this great post on stackoverflow on this subject to get a better understanding.
Well, there's a lot to say of your code. Some things have already been said, e.g. that you should make string a normal member so the allocation/deallcoation issue goes away completely (that's a general rule for C++ programs: If you don't absolutely have to use dynamic allocation, then don't, period). Also, using an appropriate smart pointer would do the memory management for you (also a general rule in C++: Don't manage the dynamic allocations yourself unless you really have to).
However let's pretend that you have to use dynamic allocation, and you have to use raw pointers and direct new and delete here. Then another important rule comes in (which actually isn't a C++ specific rule, but a general OO rule): Don't make the member public. Make it a private member, and offer a public member function for setting it. That public member function then can properly delete the old object before assigning the pointer to the new one. Note that as soon as you assigned the pointer, unless you've stored the old value elsewhere, the old value is lost forever, and if the object has not been deleted up to then, you can't delete it later.
You also want to consider whether it is really a good idea to take ownership of an object passed to you by pointer (and assigning to a pointer member which has a delete in the destructor is a ― not very obvious ― way to pass ownership). This complicates the object lifetime management because you have to remember whether you passed a certain object to an ownership-claiming object (this is not an issue if you have a strict policy of always passing to ownership-claiming objects, though). As usual, smart pointers may help here; however you may consider whether it is a better option to make a copy of the passed object (for std::string it definitely is, but then, here it's better to have a direct member anyway, as mentioned above).
So here's a full list of rules, where earlier rules take precedence to later unless there's a good reason not to use it:
Don't use dynamical allocation.
Manage your dynamical allocation with smart pointers.
Use new only in constructors and delete only in the corresponding destructor.
Always have the new and delete for a specific pointer in member functions of the same class. (Actually the previous rule is a special case of this one, but a special case which should be preferred to the general one.)
Here's a more idiomatic C++ program:
class Foo {
public:
std::string ace;
Foo() : ace() {
// nothing to do here. ace knows how to create itself…
}
// and copy itself…
Foo(const Foo& other) : ace(other.ace) {}
// and clean up after itself…
~Foo() {
}
// and copy/assign itself…
Foo& operator=(const Foo& other) {
this->ace = other.ace;
return *this;
}
};
void UI::ButtonPressed() {
// `new` is not needed here, either!
Foo foo;
ui->label = foo.ace; //Set some text on the GUI
// `delete` is not needed here
}
If you really need to call new, always use an appropriate smart pointer -- Writing delete is banished from modern C++ ;)
I'm coming from C# and trying to translate some of my practices into C++. I've used dependency injection in various places throughout my code using raw pointers. Then I decide to replace the raw pointers with std::shared_ptr's. As part of that process it was suggested that I consider using stack allocated automatic variables rather than dynamically allocating them (see this question although that question was in the context of unique_ptr so maybe that is different).
I believe the below example shows the use of automatic variables.
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
~MyClass()
{
appService_.Destroy(something);
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
In the above example, when customAppservice and myclass go out of scope how do I know which will be destroyed first? If customAppService is destroyed first than the MyClass destructor will fail. Is this a good reason to use shared_ptr instead in this scenario or is there a clean way around this?
UPDATE
ApplicationService is a class that is a wrapper around global functions needed to interact with a 3rd party library that my code uses. I have this class as I believe it's the standard way to support unit testing and stubbing/mocking of free standing functions. This class simply delegates calls to the corresponding global functions. The call appService_.Destroy(something); is actually destroying an object used by each specific instance of MyClass not destroying anything do with the Application class itself.
The answer is: you don't need to know, as your design is broken, anyway.
First, a Destroy sounds like a bad idea, furthermore if called in an object that is not responsible for the destruction of the other object. The code from the Destroy method belongs into ApplicationService's destructor (which is hopefully virtual, although in this case it doesn't actually need to), which in contrast to C# gets called at a perfectly determined point in time.
Once you've done this, you will (hopefully) realize, that it is not the responsibility of MyClass to destroy the appService_, as it does not own it. It is the responsibility of the ConsumerClass (or rather the DoSomething method), which really manages the actual service and which does actually destroy it automatically once you've moved Destroy's code into the destructor. Isn't it nice how RAII does make happen everything in a clean and automatic way?
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
class ApplicationService
{
public:
virtual ~ApplicationService()
{
//code from former Destroy method
}
}
class CustomApplicationService
{
public:
virtual ~CustomApplicationService()
{
//code from former Destroy method
}
}
This is IMHO the perfect clean C++ way around it and the problem is definitely not a reason to spam shared_ptrs. Even if you really need a dedicated Destroy method and cannot move the code into the destructor (which I would take as a motivation for overthinking the design), then you would still call Destroy from DoSomething as again, MyClass is not responsible for destroying the appService_.
EDIT: According to you update (and my stupid overlooking of the something argument), your design seems indeed quite correct (at least if you cannot mess with changing the ApplicationService), sorry.
Allthough class members should get destroyed in reverse order of construction, I'm not sure this also holds for local automatic variables. What you could do to make sure the destructors get called in a defined order is introduce nested scopes using simple blocks:
void DoSomething()
{
CustomApplicationService customAppService;
{
MyClass myclass(customAppService);
myclass...
} // myclass destroyed
} // customAppService destroyed
Of course there is still completely no need to use dynamic allocation, let aside shared_ptrs. Although the nested blocks blow the code a bit, it is nothing against the ugliness of dynamic allocation applied in a non-dynamic way and without reason and it at least "looks nice in a semantic way" with customAppService's declaration on top of the block ;)
In C++, objects, in general, are destroyed in the order that is exact opposite of the order they were created in.
Based on your example, MyClass will be destroyed before CustomApplicationService
The exception is when a destructor is called explicitly. However, I don't think you should concern yourself with this exception at this stage.
Another subtlety is called static initialization order fiasco . However, this does not apply to automatic (stack) variables.
Edit:
From C++2003 - looked for 'reverse order'
6.6.0.2
On exit from a scope (however accomplished), destructors (12.4) are called for all
constructed objects with automatic storage duration (3.7.2) (named objects or
temporaries) that are declared in that scope, in the reverse order of their
declaration. ... [Note: However, the program can be terminated (by calling exit()
or abort()(18.3), for example) without destroying class objects with automatic
storage duration. ]
So I have declared a vector in my class header like this:
...
private:
vector<Instruction> instructions;
...
Then in the .cpp implementation in the constructor, I try to initialize it like this:
instructions = new vector<Instruction>();
Xcode tells me: No viable overloaded '='
I am basically trying to get this class to behave like I would expect in java, where instances of the class retain this vector. Thats why I wanted to dynamically allocate it using new, so as to make sure that it doesn't get lost on the stack or something. Any help would be appreciated with this, thanks so much.
In order to do what you're trying to do the instructions = new vector<Instruction>() line is entirely unnecessary. Simply remove it. The vector will automatically get default-constructed when an instance of your class gets constructed.
An alternative is to make instructions into a pointer, but there doesn't appear to be any reason to do this here.
when you write
vector<Instruction> instructions;
you already have instantiated instructions to whatever memory model the user of your class is using e.g.
class YourClass
{
vector<Instruction> instructions;
};
...
int main()
{
YourClass class1; // stack
std::unique_ptr<YourClass> class2(new YourClass); // heap
...
}
In your class, you declare a std::vector<Instruction>. new vector<Instruction>(); returns you a std::vector<Instruction>*.
operator new returns a pointer, so you have a type mismatch.
The real issue is the fact that you are doing it at all. Do you have a good reason for dynamically allocating that vector? I doubt it, just omit that entirely as it will be allocated along with instances of your type.
You have a member value but you try to initialize it from a vector<Instruction>*. Initialize it from vector<Instruction> or change the declaration to a pointer. If you go down the second route, you need to observe the rule of three.
You might also want to get a decent C++ book from this list.
Also, I think you have a using namespace std; in your header which is bad.
Do not use new in C++ unless you know what you are doing. (Which you do not, currently.)
Instead use automatic objects. You already defined instructions to be an automatic object. You just need to init it as if it were one:
class wrgxl {
public:
wrgxl()
: instructions() // this initializes the vector using its default constructor
{
// nothing needed here
}
...
private:
vector<Instruction> instructions;
...
};
The initialization of instructions in the constructor's initialization list is optional, though, if you only want to call the default constructor anyway. So in this case, this would be enough:
wrgxl()
{
}
If you wanted to dynamically allocate a vector, you would need to make instructions a pointer to a vector. But this rarely ever make sense, since the vector already allocates its data dynamically, but wraps this, so you do not have to deal with the ugly details resulting from this.
One of those details is that, if you have a dynamically allocated object in a class, you will then have to worry about destruction, copy construction, and copy assignment for that class.
As Kerrek already pointed out, you will need to have a good C++ book in order to properly learn C++. Make your pick.
I think you are confusing C++'s with C#'s syntax.
First, unlike in many languages, variables allocated on the stack (such as yours), are initialized by calling the default constructor, so I suspect that what you are doing is unnecessary.
Second, in order to do what you are trying to do, you use the following syntax:
instructions = vector<Instruction>();
however, as I said, this is likely redundant (and wasteful on a non-optimizing compiler as it might call both the constructor and the assignment operator). A much better way to do this is found in sbi's answer.
Third, unlike in C#, the new operator allocates memory on the heap and returns a pointer to the newly allocated data. Your variable instructions is not a pointer, thus the error.