class Base {
public:
Base() {}
virtual void print()const = 0;
protected:
virtual ~Base() { std::cout << "Base destructor\n\n"; }
};
int main()
{
//std::vector<std::unique_ptr<Base>> v1;
//The line above won't compile because: 'Base::~Base': cannot access protected member declared in class 'Base'
std::vector<std::shared_ptr<Base>> v2;
return 0;
}
What is trying to call the destructor when I am creating the vector? Why it won't compile for the unique_ptr vector but would compile for the shared_ptr vector?
Local variables v1 and v2 have automatic storage duration and will be automatically destructed when they go out of scope. The std::vector is irrelevant here: inside vector::~vector() the compiler will generate code for element destructors. Even if a vector is always empty (this is a run-time property!), this code still has to be generated. So let's simplify the code:
std::unique_ptr<Base> v1;
std::shared_ptr<Base> v2;
When v1 goes out of scope, it has to be destroyed. The destructor generated by the compiler boils down to (*):
~unique_ptr() {
delete ptr;
}
To generate code for delete ptr, the compiler needs the accessible destructor. It is protected, so the compilation fails.
Now let's look at v2. The compiler has to generate the destructor, too. But shared_ptr has a type-erased deleter for a managed object. This means that a managed object destructor will be called indirectly – through a virtual function:
struct shared_ptr_deleter_base {
virtual void destroy() = 0;
virtual ~shared_ptr_deleter_base() = default;
};
~shared_ptr() {
// member shared_ptr::deleter has type shared_ptr_deleter_base*
if (deleter)
deleter->destroy();
}
To generate code for deleter->destroy(), you don't need to access Base::~Base() at all. The default constructor of shared_ptr simply sets deleter to a null pointer:
shared_ptr() {
deleter = nullptr;
}
That's why std::shared_ptr<Base> v2; compiles: not only Base::~Base() is not called at the run-time, no call is ever generated by the compiler at the compile-time.
Let's consider this line:
std::shared_ptr<Base> v2(new Base());
Now the following constructor is called (note that it is a template with a separate parameter U that can be different from T in shared_ptr<T>):
template<class U>
shared_ptr(U* ptr) {
deleter = new shared_ptr_deleter<U>(ptr);
}
Here shared_ptr_deleter is a concrete class derived from shared_ptr_deleter_base:
template<class T>
struct shared_ptr_deleter : shared_ptr_deleter_base {
T* ptr;
shared_ptr_deleter(T* p) : ptr(p) {}
virtual void destroy() {
delete ptr;
}
};
To generate code for the constructor taking new Base(), the compiler has to generate code for shared_ptr_deleter<Base>::destroy(). Now it fails because the Base::~Base() is inaccessible.
(*) I present only simplified definitions just to demonstrate basic ideas without going into all the details that are not relevant to understanding the problem in question.
std::unique_ptr can't access the destructor of Base because it's protected. std::shared_ptr uses a polymorphic deleter so std::shared_ptr only needs to access the destructor of Base when you create a new std::shared_ptr.
// this fails because the destructor of Base is inaccessible
std::unique_ptr<Base> a;
// this is ok because the destructor isn't required to instantiate the type
std::shared_ptr<Base> b;
// this fails because make_shared needs the destructor
std::shared_ptr<Base> c = std::make_shared<Base>();
"Polymorphic deleter" basically means that std::shared_ptr stores a pointer to a function that destroys the object. std::unique_ptr uses a "static deleter" that destroys the object directly. Here's some pseudo-code:
struct shared_ptr {
~shared_ptr() {
deleter();
}
void (*deleter)(); // pointer to function that destroys the object
};
// shared_ptr doesn't try to call the destructor directly so we don't need access
// so this is ok
shared_ptr a;
shared_ptr make_shared() {
// here we generate (with templates) a function that calls Base::~Base
// then we set "deleter" to point to that function
// the destructor has to be accessible for us to do this
}
// so we get an error here
shared_ptr b = make_shared();
struct unique_ptr {
~unique_ptr() {
// unique_ptr calls the Base destructor directly
// unique_ptr needs access to the destructor to instantiate the type
}
};
// so we get an error here
unique_ptr c;
In your situation, Base happens to be abstract so you can use std::shared_ptr<Base> because you'll never need to write std::make_shared<Base>(). As long as subclasses of Base have public destructors, std::make_shared will be able to access them without giving you errors.
Related
I have implemented a class reference<T> that keeps track of the amount of references to a T which derives from reference_countable.
I have a problem with it with respect to forward declaring the T of the reference<T>, similar to that of std::unique_ptr<T>. With std::unique_ptr<T> the issue comes from the destructor not beeing known, so all you have to do is put the destructor of your class into the cpp file, like so:
header:
class MyClass;
class A
{
std::unique_ptr<MyClass> my_class;
}
implementation:
A:~A() = default;
However, in my version, where std::unique_ptr<MyClass> is replaced by reference<MyClass>, the reference_countable must also be decremented and incremented. Which requires me to also put the copy-assignment and copy-constructor of A in cpp file when MyClass is only forward declared.
Is there a way to avoid having to put the implementation for these three functions in the cpp file for all classes with a reference<T> member?
I've tried to describe it as simple as I can, but for more detail, here is a simple version of the problem. Specifically, the need to define the copy-constructor of A in a.cpp.
my_class.h
#pragma once
#include "minimal_ref_counter.h"
class MyClass : public minimal_reference_countable
{
};
a.h
#pragma once
#include "minimal_ref_counter.h"
class MyClass;
class A
{
public:
A();
~A();
A(const A&);
minimal_reference_counter<MyClass> my_class;
};
a.cpp
#include "test.h"
#include "myclass.h"
A::A()
: my_class(new MyClass())
{}
A::~A() = default;
A::A(const A&) = default;
some_other_code.cpp
#include "a.h"
void some_function()
{
A a1;
A a2 = a1; // this code does not compile without the copy assignment operator beeing implemented externally.
}
minimal_ref_counter.h
#pragma once
#include <atomic>
class minimal_reference_countable
{
template<typename T>
friend class minimal_reference_counter;
std::atomic_int m_references = 0;
auto reference_count() const { return m_references.load(); }
void decrement() { --m_references; }
void increment() { ++m_references; }
};
template<typename T>
class minimal_reference_counter
{
public:
minimal_reference_counter(T* t = nullptr)
{
assign(t);
}
~minimal_reference_counter()
{
reset();
}
minimal_reference_counter(const minimal_reference_counter& r)
{
*this = r;
}
minimal_reference_counter(minimal_reference_counter&& r)
{
*this = std::move(r);
}
minimal_reference_counter& operator=(const minimal_reference_counter& r)
{
assign(r.m_ptr);
return *this;
}
minimal_reference_counter& operator=(minimal_reference_counter&& r)
{
assign(r.m_ptr);
r.reset();
return *this;
}
void reset()
{
if (!m_ptr) return;
m_ptr->decrement();
if (m_ptr->reference_count() == 0)
{
delete m_ptr;
}
m_ptr = nullptr;
}
private:
void assign(T* ptr)
{
reset();
m_ptr = ptr;
if (m_ptr) m_ptr->increment();
}
T* m_ptr = nullptr;
};
C++ templates are lazy. Instantiations are deferred until necessary. The reason to put the destructor in the cpp file when you have a member std::unique_ptr of an incomplete type, later completed, is that the destructor needs the destructor of unique_ptr, thus instantiating it, which needs the destructor of the pointed-to type which requires that type to be complete. This chain of dependencies triggered by the definition of the destructor must be deferred until such time as the pointed-to type is complete.
In your reference counted pointer case, you wonder if the copy constructor, copy assignment operator, and destructor of the pointer necessarily require completeness of the pointed-to type, and likewise their instantiations be deferred until such time as the pointed to type is complete.
Because the pointer destructor potentially invokes the destructor of the pointed-to type, that type necessarily must be complete when the pointer destructor is instantiated. This is similar to unique_ptr and so should be unsurprising.
Similarly, the pointer copy assignment potentially invokes the destructor of the pointed-to type. It replaces the pointee with another pointee and decrements the original pointee's reference count and destroys it if necessary. So, for the same reason as the destructor, the pointer copy assignment operator requires the pointed-to type necessarily be complete when it is instantiated.
The copy constructor is more subtle. No potential destructions of the pointed-to type are invoked. However, with this implementation, we act on a base class of the pointed-to type to increment the reference count. This requires completeness, as otherwise there are no base classes. So, with this implementation, yes, the poitned-to type necessarily must be complete when the copy constructor is instantiated.
There are alternative implementations, of course. One could keep both a T* and a minimal_reference_counter<T>*, instead of finding the latter from the former as a base class. shared_ptr does this. In fact, one could also store the destructor as a function pointer and not require the other awkward instantiation deferrals. shared_ptr does this too.
I have a simple container class that points to an abstract class and I have functions to get/set the pointer in the container class. More concretely, the class looks like this:
class Container
{
Abstract* thing;
public:
void set(Abstract &obj)
{
thing = &obj; //danger of dangling pointer
}
Abstract* get()
{
return thing;
}
};
Abstract is an abstract class. As can be seen already, there's a danger of a dangling pointer. I know that I could make a copy of the object (new) and then point to it. But I can't create an instance of an abstract class. What solutions to this are there?
The following are just more information:
Class definitions
class Abstract
{
public:
virtual void something() = 0;
};
class Base : public Abstract
{
int a;
public:
Base() {}
Base(int a) : a(a){}
virtual void something()
{
cout << "Base" << endl;
}
};
class Derived : public Base
{
int b;
public:
Derived() {}
Derived(int a, int b) : Base(a), b(b){}
virtual void something()
{
cout << "Derived" << endl;
}
};
Simple tests
void setBase(Container &toSet)
{
Base base(15);
toSet.set(base);
}
void setDerived(Container &toSet)
{
Derived derived(10, 30);
toSet.set(derived);
}
int main()
{
Container co;
Base base(15);
Derived derived(10, 30);
Base *basePtr;
Derived *derivedPtr;
//This is fine
co.set(base);
basePtr = static_cast<Base *>(co.get());
basePtr->something();
//This is fine
co.set(derived);
derivedPtr = static_cast<Derived *>(co.get());
derivedPtr->something();
//Reset
basePtr = nullptr;
derivedPtr = nullptr;
//Dangling pointer!
setBase(co);
basePtr = static_cast<Base *>(co.get());
basePtr->something();
//Dangling pointer!
setDerived(co);
derivedPtr = static_cast<Derived *>(co.get());
derivedPtr->something();
return 0;
}
What you need to do is to define your memory ownership concretely.
Container::set accepts an instance of Abstract by reference, which usually does not imply an ownership transfer:
void set(Abstract &obj){...} // Caller retains ownership of obj, but now we have a weak reference to it
Then the onus of deletion is not on you.
Container::get returns a pointer which implies ownership, indicating that someone who calls set should not invalidate the passed object.
Abstract* get(){...}
This could be problematic, as you've stated.
You have a few options
Encode these memory ownership semantics within Container with proper documentation (Code by contract)
Use a smart pointer like std::shared_ptr
In the former case, whether it works or not depends on the user reading and understanding your API, and then behaving nicely with it. In the latter case, the pointer object owns itself, and will delete the allocated memory when the last instance goes out of scope.
void set(std::shared_ptr<Abstract> obj){...}
// now Container participates in the lifetime of obj,
// and it's harder to nullify the underlying object
// (you'd have to be intentionally misbehaving)
If you are worried about the object being deallocated elsewhere resulting in a dangling pointer, you could use boost smart pointers.
Boost smart pointers would provide you the service of book keeping and help to avoid such a case.
Some information can be found here :
smart pointers (boost) explained
This is what std::unique_ptr is for:
class Container
{
std::unique_ptr<Abstract> thing;
public:
void set(std::unique_ptr<Abstract> obj)
{
thing = obj;
}
Abstract* get()
{
return thing.get();
}
};
Now the Abstract object is "owned" by Container and will be cleaned up automatically when the Conatiner is destroyed.
If you want a pointer that might live longer, or might be shared between mulitple containers, use std::shared_ptr instead.
I was reading the Smart Pointer Programming Techniques provided in the boost documentation.
In the Section "using abstract classes for implementation hiding", they provide a nice idiom to fully hide an implementation behind pure virtual interface. For example:
// Foo.hpp
#include <memory>
class Foo {
public:
virtual void Execute() const = 0;
protected:
~Foo() = default;
};
std::shared_ptr<const Foo> MakeFoo();
and
// Foo.cpp
#include "Foo.hpp"
#include <iostream>
class FooImp final
: public Foo {
public:
FooImp() = default;
FooImp(const FooImp&) = delete;
FooImp& operator=(const FooImp&) = delete;
void Execute() const override {
std::cout << "Foo::Execute()" << std::endl;
}
};
std::shared_ptr<const Foo> MakeFoo() {
return std::make_shared<const FooImp>();
}
Regarding the protected, non-virtual destructor in class Foo, the document states:
Note the protected and nonvirtual destructor in the example above. The
client code cannot, and does not need to, delete a pointer to X; the
shared_ptr<X> instance returned from createX will correctly call
~X_impl.
which I believe I understand.
Now, it seems to me that this nice idiom could be used to produce a singleton-like entity if a factory function returned std::unique_ptr<Foo>; the user would be forced to move the pointer, with a compile-time guarantee that no copies exist.
But, alas, I cannot make the code work unless I change ~Foo() = default from protected to public, and I do not understand why.
In other words, this does not work:
std::unique_ptr<const Foo> MakeUniqueFoo() {
return std::make_unique<const FooImp>();
}
My questions:
Could you explain me why do I need to make public ~Foo() = default?
Would it be dangerous to just remove protected?
Is the singleton-like idea even worth it?
The issue has to do with how deleters work in smart pointers.
In shared_ptr, the deleter is dynamic. When you have std::make_shared<const FooImp>();, the deleter in that object will call ~FooImpl() directly:
The object is destroyed using delete-expression or a custom deleter that is supplied to shared_ptr during construction.
That deleter will be copied onto the shared_ptr<const Foo> when it's created.
In unique_ptr, the deleter is part of the type. It's:
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
So when you have unique_ptr<const Foo>, that will call ~Foo() directly - which is impossible since ~Foo() is protected. That's why when you make Foo() public, it works. Works, as in, compiles. You would have to make it virtual too - otherwise you'd have undefined behavior by only destructing the Foo part of FooImpl.
It's not dangerous. Unless you forget to make the destructor virtual, which, it bears repeating, will cause undefined behavior.
This isn't really singleton-like. As to whether or not it's worth it? Primarily opinion based.
Every shared_ptr stores 4 things: a pointer, a strong reference count, a weak reference count, and a deleter.
The deleter gets the type from which the shared_ptr was constructed from, and deletes that type, not the exposed type. If you cast it to a base shared_ptr, the derived deleter is still stored.
unique_ptr does not, by default, store such a stateful deleter.
The design reason behind this is that a shared_ptr is already managing extra resources: adding that deleter is cheap, given that you are already managing the reference counts.
For unique_ptr, without a stateful deleter, the overhead for it is basically identical to a raw pointer. Adding a stateful deleter by default would make unique_ptrs significantly more expensive.
While they are both smart pointers, unique_ptr is really minimal, while shared_ptr is far more complex.
You can get around this by appending a stateful deleter to unique_ptr.
struct stateful_delete {
void const* ptr = nullptr;
void(*f)(void const*) = nullptr;
template<class T>
stateful_delete(T const* t):
ptr(t),
f([](void const* ptr){
delete static_cast<T const*>(ptr);
})
{}
template<class T>
void operator()(T*)const{
if (f) f(ptr);
}
};
template<class T>
using unique_ptr_2 = std::unique_ptr<T, stateful_delete>;
template<class T>
unique_ptr_2<T> unique_wrap_2(T* t) {
return {t, t};
}
template<class T, class...Args>
unique_ptr_2<T> make_unique_2(Args&&...args) {
return unique_wrap( new T(std::forward<Args>(args)...) );
}
such unique_ptr_2 are 3 times as large as a unique_ptr. They do not do an extra allocation (unlike shared_ptr). And they will work with your non-virtual protected ~Foo with a public ~FooImpl.
You could reduce the size of unique_ptr_2 down to 2 pointers if we use the make_shared technique of doing a unified allocation, and store the equivalent of the ptr and f on the heap. I'm uncertain if that complexity is worth the savings.
Based on Barry's answer an alternative to making it public is defining your own deleter which has access to your class' ~Foo() method.
Example (tried with VS2013):
template <typename T>
class deleter
{
public:
void operator()(T* a)
{
// Explicitly call the destructor on a.
a->~A();
}
};
class A {
friend class deleter<A>; // Grant access to the deleter.
protected:
~A() {
// Destructor.
}
};
std::unique_ptr<A, deleter<A>> MakeA()
{
return std::unique_ptr<A, deleter<A>>(new A());
}
I made some testing with shared_ptr,and i can't think out the matter below.I just started to learn the boost library. Is there anybody can tell me the reason?
#include <boost\shared_ptr.hpp>
#include <iostream>
class A
{
public:
virtual void sing()
{
std::cout<<"A";
}
protected: virtual ~A() {};
};
class B : public A
{
public:
virtual void sing()
{
std::cout << "B";
}
virtual ~B() {};
};
int foo()
{
boost::shared_ptr<A> pa(new B());
pa->sing();
delete static_cast<B*>(pa.get());
delete pa.get(); //this line has a problem error C2248: “A::~A”: can't access protected memmber(declared in class“A")
return 0;
}
int main()
{
foo();
return 0;
}
but it can be compiled when that line is commented out. Surely it doesn't mean that the shared_ptr will delete the pointer internally maintained out of the main function, just like what i did. Is there any difference between the pointer returned by pa.get() and the pointer internally maintained?
I believe that delete is called during destruction of the shared_ptr on the type of the pointer passed into the constructor. Have a look at the constructor here:
http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#constructors
So when your pa goes out of scope, B::~B( ) is called rather than the destructor of the type contained - A::~A ( which would be impossible because it's declared protected).
Actually, it's a bit more complicated than that: the machinery behind shared_ptr is quite complicated.
First, let us prove there is no specific access rights granted to shared_ptr:
int main() {
A* a = new B();
std::shared_ptr<A> p(a); // expected-error
}
This will result in an error because the destructor of A is not accessible. Interestingly, the error occurs at the point of construction, which is a clue...
So, what is the magic behind shared_ptr ?
Internally, a shared_ptr keeps much more than a simple pointer and reference counts. A shared_ptr is built with a deleter, in charge of destructing the instance of the object. Where the design really shines is that this deleter is instantiated in the constructor and thus may know more type information than the bare shared_ptr type lets on.
A simplified demo:
template <typename T>
struct shared_holder {
typedef void (*Disposer)(T*);
explicit shared_holder_base(T* t, Disposer d): _ptr(t), _disposer(d) {}
void dispose() { _disposer(_ptr); _ptr = 0; }
T* _ptr;
Disposer _disposer;
};
template <typename U, typename T>
void dispose(T* t) { delete static_cast<U*>(t); }
template <typename T>
class shared_ptr {
typedef shared_holder<T> holder;
public:
shared_ptr(): _holder(0), _ptr(0) {}
template <typename U>
explicit shared_ptr(U* u):
_holder(new holder(u, dispose<U, T>)), _ptr(_holder->_ptr) {}
private:
holder* _holder;
T* _ptr;
};
The key insight is that the disposer is instantiated from the static type known by the constructor; this is why:
shared_ptr<A>(new B) works
A* a = new B; shared_ptr<A>(a) does not
You can read the Boost headers, the machinery behind the shared_ptr is quite interesting.
As an exercise for the reader, why does shared_ptr<T> has a _ptr member ?
When you have:
boost::shared_ptr<A> pa(new B());
...you are calling boost::shared_ptr constructor and are dealing with TWO template parameters:
shared_ptr template type T (A in your case);
get() returns T* so when you tried:
delete pa.get();
...you tried to access ~A() which is accessible only to As children and therefore got an error.
In the following line:
delete static_cast<B*>(pa.get());
...you were downcasting A* to B* and called delete on B* thus invoking ~B() to which you had access. (~B() is always calling ~A() for ~A() is declared as virtual)
shared_ptr constructor argument template type Y (B in your case) with the
requirement that Y* must be convertible to T* (you can upcast
B* to A* as B inherits A in your case).
~shared_ptr() calls delete on Y* (B* in your case; ~B() can access ~A() and
calls it) and this is what happens when pa goes out of scope (and this is how shared_ptr accessed base class protected destructor which was your original question).
boost::shared_ptr keeps internally a single pointer. When creating boost::shared_ptr you are passing to its constructor a SINGLE pointer which can be regarded as / converted to pointer to any of those TWO template argument types.
I believe it is because the definition of the boost template declares the sharedpointer a friend of the <Class T> class from your template instantiation.
This is a snipet I copied from the boot shared pointer header file.
// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
private:
template<class Y> friend class shared_ptr;
template<class Y> friend class weak_ptr;
#endif
In C++, I want to define an object as a member of a class like this:
Object myObject;
However doing this will try to call it's parameterless constructor, which doesn't exist. However I need the constructor to be called after the containing class has done some initialising. Something like this.
class Program
{
public:
Object myObject; //Should not try to call the constructor or do any initializing
Program()
{
...
//Now call the constructor
myObject = Object(...);
}
}
Store a pointer to an Object rather than an actual Object
thus:
class Program
{
public:
Object* myObject; // Will not try to call the constructor or do any initializing
Program()
{
//Do initialization
myObject = new Object(...); // Initialised now
}
}
Don't forget to delete it in the destructor. Modern C++ helps you there, in that you could use an auto_ptr shared_ptr rather than a raw memory pointer.
Others have posted solutions using raw pointers, but a smart pointer would be a better idea:
class MyClass {
std::unique_ptr<Object> pObj;
// use boost::scoped_ptr for older compilers; std::unique_ptr is a C++0x feature
public:
MyClass() {
// ...
pObj.reset(new Object(...));
pObj->foo();
}
// Don't need a destructor
};
This avoids the need to add a destructor, and implicitly forbids copying (unless you write your own operator= and MyClass(const MyClass &).
If you want to avoid a separate heap allocation, this can be done with boost's aligned_storage and placement new. Untested:
template<typename T>
class DelayedAlloc : boost::noncopyable {
boost::aligned_storage<sizeof(T)> storage;
bool valid;
public:
T &get() { assert(valid); return *(T *)storage.address(); }
const T &get() const { assert(valid); return *(const T *)storage.address(); }
DelayedAlloc() { valid = false; }
// Note: Variadic templates require C++0x support
template<typename Args...>
void construct(Args&&... args)
{
assert(!valid);
new(storage.address()) T(std::forward<Args>(args)...);
valid = true;
}
void destruct() {
assert(valid);
valid = false;
get().~T();
}
~DelayedAlloc() { if (valid) destruct(); }
};
class MyClass {
DelayedAlloc<Object> obj;
public:
MyClass() {
// ...
obj.construct(...);
obj.get().foo();
}
}
Or, if Object is copyable (or movable), you can use boost::optional:
class MyClass {
boost::optional<Object> obj;
public:
MyClass() {
// ...
obj = Object(...);
obj->foo();
}
};
You can fully control the object construction and destruction by this trick:
template<typename T>
struct DefferedObject
{
DefferedObject(){}
~DefferedObject(){ value.~T(); }
template<typename...TArgs>
void Construct(TArgs&&...args)
{
new (&value) T(std::forward<TArgs>(args)...);
}
public:
union
{
T value;
};
};
Apply on your sample:
class Program
{
public:
DefferedObject<Object> myObject; //Should not try to call the constructor or do any initializing
Program()
{
...
//Now call the constructor
myObject.Construct(....);
}
}
Big advantage of this solution, is that it does not require any additional allocations, and object memory allocated as normal, but you have control when call to constructor.
Another sample link
If you have access to boost, there is a handy object that is provided called boost::optional<> - this avoids the need for dynamic allocation, e.g.
class foo
{
foo() // default std::string ctor is not called..
{
bar = boost::in_place<std::string>("foo"); // using in place construction (avoid temporary)
}
private:
boost::optional<std::string> bar;
};
You may also be able to rewrite your code to use the constructor initializer list, if you can move off the other initialization into constructors:
class MyClass
{
MyObject myObject; // MyObject doesn't have a default constructor
public:
MyClass()
: /* Make sure that any other initialization needed goes before myObject in other initializers*/
, myObject(/*non-default parameters go here*/)
{
...
}
};
You need to be aware that following such a pattern will lead you to a path where you do a lot of work in constructors, which in turn leads to needing to grasp exception handling and safety (as the canonical way to return an error from a constructor is to throw an exception).
You can use a pointer (or a smart pointer) to do that. If you do not use a smart pointer, do make sure that your code free memory when the object is deleted. If you use a smart pointer, do not worry about it.
class Program
{
public:
Object * myObject;
Program():
myObject(new Object())
{
}
~Program()
{
delete myObject;
}
// WARNING: Create copy constructor and = operator to obey rule of three.
}
A trick that involves anonymous union and placement new
this is similar to jenkas' answer but more direct
class Program
{
public:
union{
Object myObject;
}; //being a union member in this case prevents the compiler from attempting to call the (undefined) default constructor
Program()
{
...
//Now call the constructor
new (&myObject) Object(...);
}
~Program()
{
myobject.~Object(); //also make sure you explicitly call the object's destructor
}
}
however the catch is that now you must explicitly define all the special member functions as the compiler will delete them by default.