What's a good existing class/design pattern for multi-stage construction/initialization of an object in C++?
I have a class with some data members which should be initialized in different points in the program's flow, so their initialization has to be delayed. For example one argument can be read from a file and another from the network.
Currently I am using boost::optional for the delayed construction of the data members, but it's bothering me that optional is semantically different than delay-constructed.
What I need reminds features of boost::bind and lambda partial function application, and using these libraries I can probably design multi-stage construction - but I prefer using existing, tested classes. (Or maybe there's another multi-stage construction pattern which I am not familiar with).
The key issue is whether or not you should distinguish completely populated objects from incompletely populated objects at the type level. If you decide not to make a distinction, then just use boost::optional or similar as you are doing: this makes it easy to get coding quickly. OTOH you can't get the compiler to enforce the requirement that a particular function requires a completely populated object; you need to perform run-time checking of fields each time.
Parameter-group Types
If you do distinguish completely populated objects from incompletely populated objects at the type level, you can enforce the requirement that a function be passed a complete object. To do this I would suggest creating a corresponding type XParams for each relevant type X. XParams has boost::optional members and setter functions for each parameter that can be set after initial construction. Then you can force X to have only one (non-copy) constructor, that takes an XParams as its sole argument and checks that each necessary parameter has been set inside that XParams object. (Not sure if this pattern has a name -- anybody like to edit this to fill us in?)
"Partial Object" Types
This works wonderfully if you don't really have to do anything with the object before it is completely populated (perhaps other than trivial stuff like get the field values back). If you do have to sometimes treat an incompletely populated X like a "full" X, you can instead make X derive from a type XPartial, which contains all the logic, plus protected virtual methods for performing precondition tests that test whether all necessary fields are populated. Then if X ensures that it can only ever be constructed in a completely-populated state, it can override those protected methods with trivial checks that always return true:
class XPartial {
optional<string> name_;
public:
void setName(string x) { name_.reset(x); } // Can add getters and/or ctors
string makeGreeting(string title) {
if (checkMakeGreeting_()) { // Is it safe?
return string("Hello, ") + title + " " + *name_;
} else {
throw domain_error("ZOINKS"); // Or similar
}
}
bool isComplete() const { return checkMakeGreeting_(); } // All tests here
protected:
virtual bool checkMakeGreeting_() const { return name_; } // Populated?
};
class X : public XPartial {
X(); // Forbid default-construction; or, you could supply a "full" ctor
public:
explicit X(XPartial const& x) : XPartial(x) { // Avoid implicit conversion
if (!x.isComplete()) throw domain_error("ZOINKS");
}
X& operator=(XPartial const& x) {
if (!x.isComplete()) throw domain_error("ZOINKS");
return static_cast<X&>(XPartial::operator=(x));
}
protected:
virtual bool checkMakeGreeting_() { return true; } // No checking needed!
};
Although it might seem the inheritance here is "back to front", doing it this way means that an X can safely be supplied anywhere an XPartial& is asked for, so this approach obeys the Liskov Substitution Principle. This means that a function can use a parameter type of X& to indicate it needs a complete X object, or XPartial& to indicate it can handle partially populated objects -- in which case either an XPartial object or a full X can be passed.
Originally I had isComplete() as protected, but found this didn't work since X's copy ctor and assignment operator must call this function on their XPartial& argument, and they don't have sufficient access. On reflection, it makes more sense to publically expose this functionality.
I must be missing something here - I do this kind of thing all the time. It's very common to have objects that are big and/or not needed by a class in all circumstances. So create them dynamically!
struct Big {
char a[1000000];
};
class A {
public:
A() : big(0) {}
~A() { delete big; }
void f() {
makebig();
big->a[42] = 66;
}
private:
Big * big;
void makebig() {
if ( ! big ) {
big = new Big;
}
}
};
I don't see the need for anything fancier than that, except that makebig() should probably be const (and maybe inline), and the Big pointer should probably be mutable. And of course A must be able to construct Big, which may in other cases mean caching the contained class's constructor parameters. You will also need to decide on a copying/assignment policy - I'd probably forbid both for this kind of class.
I don't know of any patterns to deal with this specific issue. It's a tricky design question, and one somewhat unique to languages like C++. Another issue is that the answer to this question is closely tied to your individual (or corporate) coding style.
I would use pointers for these members, and when they need to be constructed, allocate them at the same time. You can use auto_ptr for these, and check against NULL to see if they are initialized. (I think of pointers are a built-in "optional" type in C/C++/Java, there are other languages where NULL is not a valid pointer).
One issue as a matter of style is that you may be relying on your constructors to do too much work. When I'm coding OO, I have the constructors do just enough work to get the object in a consistent state. For example, if I have an Image class and I want to read from a file, I could do this:
image = new Image("unicorn.jpeg"); /* I'm not fond of this style */
or, I could do this:
image = new Image(); /* I like this better */
image->read("unicorn.jpeg");
It can get difficult to reason about how a C++ program works if the constructors have a lot of code in them, especially if you ask the question, "what happens if a constructor fails?" This is the main benefit of moving code out of the constructors.
I would have more to say, but I don't know what you're trying to do with delayed construction.
Edit: I remembered that there is a (somewhat perverse) way to call a constructor on an object at any arbitrary time. Here is an example:
class Counter {
public:
Counter(int &cref) : c(cref) { }
void incr(int x) { c += x; }
private:
int &c;
};
void dontTryThisAtHome() {
int i = 0, j = 0;
Counter c(i); // Call constructor first time on c
c.incr(5); // now i = 5
new(&c) Counter(j); // Call the constructor AGAIN on c
c.incr(3); // now j = 3
}
Note that doing something as reckless as this might earn you the scorn of your fellow programmers, unless you've got solid reasons for using this technique. This also doesn't delay the constructor, just lets you call it again later.
Using boost.optional looks like a good solution for some use cases. I haven't played much with it so I can't comment much. One thing I keep in mind when dealing with such functionality is whether I can use overloaded constructors instead of default and copy constructors.
When I need such functionality I would just use a pointer to the type of the necessary field like this:
public:
MyClass() : field_(0) { } // constructor, additional initializers and code omitted
~MyClass() {
if (field_)
delete field_; // free the constructed object only if initialized
}
...
private:
...
field_type* field_;
next, instead of using the pointer I would access the field through the following method:
private:
...
field_type& field() {
if (!field_)
field_ = new field_type(...);
return field_;
}
I have omitted const-access semantics
The easiest way I know is similar to the technique suggested by Dietrich Epp, except it allows you to truly delay the construction of an object until a moment of your choosing.
Basically: reserve the object using malloc instead of new (thereby bypassing the constructor), then call the overloaded new operator when you truly want to construct the object via placement new.
Example:
Object *x = (Object *) malloc(sizeof(Object));
//Use the object member items here. Be careful: no constructors have been called!
//This means you can assign values to ints, structs, etc... but nested objects can wreak havoc!
//Now we want to call the constructor of the object
new(x) Object(params);
//However, you must remember to also manually call the destructor!
x.~Object();
free(x);
//Note: if you're the malloc and new calls in your development stack
//store in the same heap, you can just call delete(x) instead of the
//destructor followed by free, but the above is the correct way of
//doing it
Personally, the only time I've ever used this syntax was when I had to use a custom C-based allocator for C++ objects. As Dietrich suggests, you should question whether you really, truly must delay the constructor call. The base constructor should perform the bare minimum to get your object into a serviceable state, whilst other overloaded constructors may perform more work as needed.
I don't know if there's a formal pattern for this. In places where I've seen it, we called it "lazy", "demand" or "on demand".
Related
There is a little code example here:
struct Data {
};
struct Init {
Data *m_data;
Init() : m_data(new Data) { }
~Init() {
delete m_data;
}
};
class Object {
private:
int m_initType;
Data *m_data;
public:
Object(const Init &init) : m_initType(0), m_data(init.m_data) { }
Object(Init &&init) : m_initType(1), m_data(init.m_data) { init.m_data = nullptr; }
~Object() {
if (m_initType==1) {
delete m_data;
}
}
};
Object can be initialized two ways:
const Init &: this initialization just stores m_data as a pointer, m_data is not owned, so ~Object() doesn't have to do anything (in this case, m_data will be destroyed at ~Init())
Init &&: this initialization transfers ownership of m_data, Object becomes the owner of m_data, so ~Object() needs to destroy it
Now, there is a function:
void somefunction(Object object);
This function is called in callInitA and callInitB:
void callInitA() {
Init x;
somefunction(x); // calls the "const Init &" constructor
}
void callInitB() {
somefunction(Init()); // calls the "Init &&" constructor
}
Now, here's what I'd like to accomplish: in the callInitA case, I'd like to make the compiler to optimize away the destructor call of the resulting temporary Object (Object is used frequently, and I'd like to decrease code size).
However, the compiler doesn't optimize it away (tested with GCC and clang).
Object is designed so it doesn't have any functions which alter m_initType, so the compiler would be able to find out that if m_initType is set to 0 at construct time, then it won't change, so at the destructor it is still be 0 -> no need to call destructor at all, as it would do nothing.
Even, m_initType is an unnecessary member of Object: it is only needed at destruct time.
Do you have any design ideas how to accomplish this?
UPDATE: I mean that using some kind of c++ construct (helper class, etc.). C++ is a powerful language, maybe with some kind of c++ trickery this can be done.
(My original problem is more complex that this simplified one: Object can be initialized with other kind of Init structures, but all Objects constructors boils down to getting a "Data*" somehow)
void callInitA() {
Init x;
somefunction(x); // calls the "const Init &" constructor
}
The destruction of x cannot be optimized away, regardless of the contents of Init. Doing so would violate the design of the language.
It's not just a matter of whether Init contains resources or not. Init x, like all objects, will allocate space on the stack that later needs to be cleaned up, as an implicit (not part of code that you yourself write) part of the destructor. It's impossible to avoid.
If the intention is for x to be an object that somefunction can call without having to repeatedly create and delete references to x, you should be handling it like this:
void callInitA(Init & x) { //Or Init const& x
somefunction(x); // calls the "const Init &" constructor
}
A few other notes:
Make sure you implement the Rule of Five (sometimes known as Rule of Three) on any object that owns resources.
You might consider wrapping all pointers inside std::unique_ptr, as it doesn't seem like you need functionality beyond what std::unique_ptr offers.
Your m_initType actually distinguishes between two kinds of Objects - those which own their memory and those which don't. Also, you mention that actually there are many kinds of Objects which can be initialized with all sorts of inputs; so actually there are all sorts of Objects. That would suggest Object should better be some abstract base class. Now, that wouldn't speed anything up or avoid destructor calls, but it might make your design more reasonable. Or maybe Object could be an std::variant (new in C++17, you can read up on it).
But then, you say that temporary Objects are "used frequently". So perhaps you should go another way: In your example, suppose you had
template <bool Owning> class Object;
which you would then specialize for the non-owning case, with only a const Init& constructor and default destruction, and the owning case, with only an Init&& constructor (considering the two you mentioned) and a destructor which deletes. This would mean templatizing the code that uses Object, which many mean larger code size, as well as having to know what kind of Objects you pass in; but if would avoid the condition check if that really bugs you so much.
I'd like to decrease code size
I kind of doubt that you do. Are you writing code for an embedded system? In that case it's kind of strange you use lots of temporary Objects which are sort-of polymorphic.
I want to open a file in a class constructor. It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out? If this is possible, how to handle it in a non-throw constructor?
If an object construction fails, throw an exception.
The alternative is awful. You would have to create a flag if the construction succeeded, and check it in every method.
I want to open a file in a class constructor. It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out?
Yes.
If this is possible, how to handle it in a non-throw constructor?
Your options are:
redesign the app so it doesn't need constructors to be non-throwing - really, do it if possible
add a flag and test for successful construction
you could have each member function that might legitimately be called immediately after the constructor test the flag, ideally throwing if it's set, but otherwise returning an error code
This is ugly, and difficult to keep right if you have a volatile group of developers working on the code.
You can get some compile-time checking of this by having the object polymorphically defer to either of two implementations: a successfully constructed one and an always-error version, but that introduces heap usage and performance costs.
You can move the burden of checking the flag from the called code to the callee by documenting a requirement that they call some "is_valid()" or similar function before using the object: again error prone and ugly, but even more distributed, unenforcable and out of control.
You can make this a little easier and more localised for the caller if you support something like: if (X x) ... (i.e. the object can be evaluated in a boolean context, normally by providing operator bool() const or similar integral conversion), but then you don't have x in scope to query for details of the error. This may be familiar from e.g. if (std::ifstream f(filename)) { ... } else ...;
have the caller provide a stream they're responsible for having opened... (known as Dependency Injection or DI)... in some cases, this doesn't work that well:
you can still have errors when you go to use the stream inside your constructor, what then?
the file itself might be an implementation detail that should be private to your class rather than exposed to the caller: what if you want to remove that requirement later? For example: you might have been reading a lookup table of precalculated results from a file, but have made your calculations so fast there's no need to precalculate - it's painful (sometimes even impractical in an enterprise environment) to remove the file at every point of client usage, and forces a lot more recompilation rather than potentially simply relinking.
force the caller to provide a buffer to a success/failure/error-condition variable which the constructor sets: e.g. bool worked; X x(&worked); if (worked) ...
this burden and verbosity draws attention and hopefully makes the caller much more conscious of the need to consult the variable after constructing the object
force the caller to construct the object via some other function that can use return codes and/or exceptions:
if (X* p = x_factory()) ...
Smart_Ptr_Throws_On_Null_Deref p_x = x_factory();</li>
<li>X x; // never usable; if (init_x(&x)) ...`
etc...
In short, C++ is designed to provide elegant solutions to these sorts of issues: in this case exceptions. If you artificially restrict yourself from using them, then don't expect there to be something else that does half as good a job.
(P.S. I like passing variables that will be modified by pointer - as per worked above - I know the FAQ lite discourages it but disagree with the reasoning. Not particularly interested in discussion thereon unless you've something not covered by the FAQ.)
New C++ standard redefines this in so many ways that it's time to revisit this question.
Best choices:
Named optional: Have a minimal private constructor and a named constructor: static std::experimental::optional<T> construct(...). The latter tries to set up member fields, ensures invariant and only calls the private constructor if it'll surely succeed. Private constructor only populates member fields. It's easy to test the optional and it's inexpensive (even the copy can be spared in a good implementation).
Functional style: The good news is, (non-named) constructors are never virtual. Therefore, you can replace them with a static template member function that, apart from the constructor parameters, takes two (or more) lambdas: one if it was successful, one if it failed. The 'real' constructor is still private and cannot fail. This might sound an overkill, but lambdas are optimized wonderfully by compilers. You might even spare the if of the optional this way.
Good choices:
Exception: If all else fails, use an exception - but note that you can't catch an exception during static initialization. A possible workaround is to have a function's return value initialize the object in this case.
Builder class: If construction is complicated, have a class that does validation and possibly some preprocessing to the point that the operation cannot fail. Let it have a way to return status (yep, error function). I'd personally make it stack-only, so people won't pass it around; then let it have a .build() method that constructs the other class. If builder is friend, constructor can be private. It might even take something only builder can construct so that it's documented that this constructor is only to be called by builder.
Bad choices: (but seen many times)
Flag: Don't mess up your class invariant by having an 'invalid' state. This is exactly why we have optional<>. Think of optional<T> that can be invalid, T that can't. A (member or global) function that works only on valid objects works on T. One that surely returns valid works on T. One that might return an invalid object return optional<T>. One that might invalidate an object take non-const optional<T>& or optional<T>*. This way, you won't need to check in each and every function that your object is valid (and those ifs might become a bit expensive), but then don't fail at the constructor, either.
Default construct and setters: This is basically the same as Flag, only that this time you're forced to have a mutable pattern. Forget setters, they unnecessarily complicate your class invariant. Remember to keep your class simple, not construction simple.
Default construct and init() that takes a ctor parameters: This is nothing better than a function that returns an optional<>, but requires two constructions and messes up your invariant.
Take bool& succeed: This was what we were doing before optional<>. The reason optional<> is superior, you cannot mistakenly (or carelessly!) ignore the succeed flag and continue using the partially constructed object.
Factory that returns a pointer: This is less general as it forces the object to be dynamically allocated. Either you return a given type of managed pointer (and therefore restrict allocation/scoping schema) or return naked ptr and risk clients leaking. Also, with move schematics performance-wise this might become less desirable (locals, when kept on stack, are very fast and cache-friendly).
Example:
#include <iostream>
#include <experimental/optional>
#include <cmath>
class C
{
public:
friend std::ostream& operator<<(std::ostream& os, const C& c)
{
return os << c.m_d << " " << c.m_sqrtd;
}
static std::experimental::optional<C> construct(const double d)
{
if (d>=0)
return C(d, sqrt(d));
return std::experimental::nullopt;
}
template<typename Success, typename Failed>
static auto if_construct(const double d, Success success, Failed failed = []{})
{
return d>=0? success( C(d, sqrt(d)) ): failed();
}
/*C(const double d)
: m_d(d), m_sqrtd(d>=0? sqrt(d): throw std::logic_error("C: Negative d"))
{
}*/
private:
C(const double d, const double sqrtd)
: m_d(d), m_sqrtd(sqrtd)
{
}
double m_d;
double m_sqrtd;
};
int main()
{
const double d = 2.0; // -1.0
// method 1. Named optional
if (auto&& COpt = C::construct(d))
{
C& c = *COpt;
std::cout << c << std::endl;
}
else
{
std::cout << "Error in 1." << std::endl;
}
// method 2. Functional style
C::if_construct(d, [&](C c)
{
std::cout << c << std::endl;
},
[]
{
std::cout << "Error in 2." << std::endl;
});
}
My suggestion for this specific situation is that if you don't want a constuctor to fail because if can't open a file, then avoid that situation. Pass in an already open file to the constructor if that's what you want, then it can't fail...
One way is to throw an exception. Another is to have a 'bool is_open()' or 'bool is_valid()' functuon that returns false if something went wrong in the constructor.
Some comments here say it's wrong to open a file in the constructor. I'll point out that ifstream is part of the C++ standard it has the following constructor:
explicit ifstream ( const char * filename, ios_base::openmode mode = ios_base::in );
It doesn't throw an exception, but it has an is_open function:
bool is_open ( );
I want to open a file in a class constructor.
Almost certainly a bad idea. Very few cases when opening a file during construction is appropriate.
It is possible that the opening could fail, then the object construction could not be completed. How to handle this failure? Throw exception out?
Yep, that'd be the way.
If this is possible, how to handle it in a non-throw constructor?
Make it possible that a fully constructed object of your class can be invalid. This means providing validation routines, using them, etc...ick
A constructor may well open a file (not necessarily a bad idea) and may throw if the file-open fails, or if the input file does not contain compatible data.
It is reasonable behaviour for a constructor to throw an exception, however you will then be limited as to its use.
You will not be able to create static (compilation unit file-level) instances of this class that are constructed before "main()", as a constructor should only ever be thrown in the regular flow.
This can extend to later "first-time" lazy evaluation, where something is loaded the first time it is required, for example in a boost::once construct the call_once function should never throw.
You may use it in an IOC (Inversion of Control / Dependency Injection) environment. This is why IOC environments are advantageous.
Be certain that if your constructor throws then your destructor will not be called. So anything you initialised in the constructor prior to this point must be contained in an RAII object.
More dangerous by the way can be closing the file in the destructor if this flushes the write buffer. No way at all to handle any error that may occur at this point properly.
You can handle it without an exception by leaving the object in a "failed" state. This is the way you must do it in cases where throwing is not permitted, but of course your code must check for the error.
Use a factory.
A factory can be either an entire factory class "Factory<T>" for building your "T" objects (it doesn't have to be a template) or a static public method of "T". You then make the constructor protected and leave the destructor public. That ensures new classes can still derive from "T" but no external code other than them can call the constructor directly.
With factory methods (C++17)
class Foo {
protected:
Foo() noexcept; // Default ctor that can't fail
virtual bool Initialize(..); // Parts of ctor that CAN fail
public:
static std::optional<Foo> Create(...) // 'Stack' or value-semantics version (no 'new')
{
Foo out();
if(foo.Initialize(..)) return {out};
return {};
}
static Foo* /*OR smart ptr*/ Create(...) // Heap version.
{
Foo* out = new Foo();
if(foo->Initialize(...) return out;
delete out;
return nullptr;
}
virtual ~Foo() noexcept; // Keep public to allow normal inheritance
};
Unlike setting 'valid' bits or other hacks, this is relatively clean and extensible. Done right it guarantees no invalid objects ever escape into the wild, and writing derived 'Foo's is still straightforward. And since factory functions are normal functions, you can do a lot of other things with them that constructors can't.
In my humble opinion you should never put any code that can realistically fail into a constructor. That pretty much means anything that does I/O or other 'real work'. Constructors are a special corner case of the language, and they basically lack the ability to do error handling.
I need to store a list of various properties of an object. Property consists of a name and data, which can be of any datatype.
I know I can make a class "Property", and extend it with different PropertySubClasses which only differ with the datatype they are storing, but it does not feel right.
class Property
{
Property(std::string name);
virtual ~Property();
std::string m_name;
};
class PropertyBoolean : Property
{
PropertyBoolean(std::string name, bool data);
bool m_data;
};
class PropertyFloat : Property
{
PropertyFloat(std::string name, float data);
float m_data;
};
class PropertyVector : Property
{
PropertyVector(std::string name, std::vector<float> data);
std::vector<float> m_data;
};
Now I can store all kinds of properties in a
std::vector<Property*>
and to get the data, I can cast the object to the subclass. Or I can make a pure virtual function to do something with the data inside the function without the need of casting.
Anyways, this does not feel right to create these different kind of subclasses which only differ by the data type they are storing. Is there any other convenient way to achieve similar behavior?
I do not have access to Boost.
C++ is a multi-paradigm language. It shines brightest and is most powerful where paradigms are mixed.
class Property
{
public:
Property(const std::string& name) //note: we don't lightly copy strings in C++
: m_name(name) {}
virtual ~Property() {}
private:
std::string m_name;
};
template< typename T >
class TypedProperty : public Property
{
public:
TypedProperty (const std::string& name, const T& data)
: Property(name), m_data(data);
private:
T m_data;
};
typedef std::vector< std::shared_ptr<Property> > property_list_type;
Edit: Why using std::shared_ptr<Property> instead of Property*?
Consider this code:
void f()
{
std::vector<Property*> my_property_list;
for(unsigned int u=0; u<10; ++u)
my_property_list.push_back(new Property(u));
use_property_list(my_property_list);
for(std::vector<Property*>::iterator it=my_property_list.begin();
it!=my_property_list.end(); ++it)
delete *it;
}
That for loop there attempts to cleanup, deleting all the properties in the vector, just before it goes out of scope and takes all the pointers with it.
Now, while this might seem fine for a novice, if you're an only mildly experienced C++ developer, that code should raise alarm bells as soon as you look at it.
The problem is that the call to use_property_list() might throw an exception. If so, the function f() will be left right away. In order to properly cleanup, the destructors for all automatic objects created in f() will be called. That is, my_property_list will be properly destroyed. std::vector's destructor will then nicely cleanup the data it holds. However, it holds pointers, and how should std::vector know whether these pointers are the last ones referencing their objects?
Since it doesn't know, it won't delete the objects, it will only destroy the pointers when it destroys its content, leaving you with objects on the heap that you don't have any pointers to anymore. This is what's called a "leak".
In order to avoid that, you would need to catch all exceptions, clean up the properties, and the rethrow the exception. But then, ten years from now, someone has to add a new feature to the 10MLoC application this has grown to, and, being in a hurry, adds code which leaves that function prematurely when some condition holds. The code is tested and it works and doesn't crash - only the server it's part of now leaks a few bytes an hour, making it crash due to being out of memory about once a week. Finding that makes for many hours of fine debugging.
Bottom line: Never manage resources manually, always wrap them in objects of a class designed to handle exactly one instance of such a resource. For dynamically allocated objects, those handles are called "smart pointer", and the most used one is shared_ptr.
A lower-level way is to use a union
class Property
union {
int int_data;
bool bool_data;
std::cstring* string_data;
};
enum { INT_PROP, BOOL_PROP, STRING_PROP } data_type;
// ... more smarts ...
};
Dunno why your other solution doesn't feel right, so I don't know if this way would feel better to you.
EDIT: Some more code to give an example of usage.
Property car = collection_of_properties.head();
if (car.data_type == Property::INT_PROP) {
printf("The integer property is %d\n", car.int_data);
} // etc.
I'd probably put that sort of logic into a method of the class where possible. You'd also have members such as this constructor to keep the data and type field in sync:
Property::Property(bool value) {
bool_data = value;
data_type = BOOL_PROP;
}
I suggest boost::variant or boost::any. [Related question]
Write a template class Property<T> that derives from Property with a data member of type T
Another possible solution is to write a intermediate class managing the pointers to Property classes:
class Bla {
private:
Property* mp
public:
explicit Bla(Property* p) : mp(p) { }
~Bla() { delete p; }
// The standard copy constructor
// and assignment operator
// aren't sufficient in this case:
// They would only copy the
// pointer mp (shallow copy)
Bla(const Bla* b) : mp(b.mp->clone()) { }
Bla& operator = (Bla b) { // copy'n'swap trick
swap(b);
return *this;
}
void swap(Bla& b) {
using std::swap; // #include <algorithm>
swap(mp, b.mp);
}
Property* operator -> () const {
return mp;
}
Property& operator * () const {
return *mp;
}
};
You have to add a virtual clone method to your classes returning a pointer to a newly created copy of itself:
class StringProperty : public Property {
// ...
public:
// ...
virtual Property* clone() { return new StringProperty(*this); }
// ...
};
Then you'll be able to do this:
std::vector<Bla> v;
v.push_back(Bla(new StringProperty("Name", "Jon Doe")));
// ...
std::vector<Bla>::const_iterator i = v.begin();
(*i)->some_virtual_method();
Leaving the scope of v means that all Blas will be destroyed freeing automatically the pointers they're holding. Due to its overloaded dereferencing and indirection operator the class Bla behaves like an ordinary pointer. In the last line *i returns a reference to a Bla object and using -> means the same as if it was a pointer to a Property object.
A possible drawback of this approach is that you always get a heap operation (a new and a delete) if the intermediate objects must be copied around. This happens for example if you exceed the vector's capacity and all intermediate objects must be copied to a new piece of memory.
In the new standard (i.e. c++0x) you'll be able to use the unique_ptr template: It
can be used inside the standard containers (in contrast to the auto_ptr which must not be used in the standard containers),
offers the usually faster move semantics (it can easily passed around) and
takes care over the held pointers (it frees them automatically).
I see that there are lots of shots at trying to solve your problem by now, but I have a feeling that you're looking in the wrong end - why do you actually want to do this in the first place? Is there some interesting functionality in the base class that you have omitted to specify?
The fact that you'd be forced to switch on a property type id to do what you want with a specific instance is a code smell, especially when the subclasses have absolutely nothing in common via the base class other than a name (which is the type id in this case).
Starting with C++ 17 we have something called as std::variant and std::any.
std::variant
An instance of std::variant at any given time either holds a value of one of its alternative types, or in the case of error - no value.
std::any
The class any describes a type-safe container for single values of any copy constructible type.
An object of class any stores an instance of any type that satisfies the constructor requirements or is empty, and this is referred to as the state of the class any object. The stored instance is called the contained object. Two states are equivalent if they are either both empty or if both are not empty and if the contained objects are equivalent.
The non-member any_cast functions provide type-safe access to the contained object.
You can probably do this with the Boost library, or you could create a class with a type code and a void pointer to the data, but it would mean giving up some of the type safety of C++. In other words, if you have a property "foo", whose value is an integer, and give it a string value instead, the compiler will not find the error for you.
I would recommend revisiting your design, and re-evaluating whether or not you really need so much flexibility. Do you really need to be able to handle properties of any type? If you can narrow it down to just a few types, you may be able to come up with a solution using inheritance or templates, without having to "fight the language".
In RAII, resources are not initialized until they are accessed. However, many access methods are declared constant. I need to call a mutable (non-const) function to initialize a data member.
Example: Loading from a data base
struct MyClass
{
int get_value(void) const;
private:
void load_from_database(void); // Loads the data member from database.
int m_value;
};
int
MyClass ::
get_value(void) const
{
static bool value_initialized(false);
if (!value_initialized)
{
// The compiler complains about this call because
// the method is non-const and called from a const
// method.
load_from_database();
}
return m_value;
}
My primitive solution is to declare the data member as mutable. I would rather not do this, because it suggests that other methods can change the member.
How would I cast the load_from_database() statement to get rid of the compiler errors?
This is not RAII. In RAII you would initialize it in the constructor, which would solve your problems.
So, what you are using here is Lazy. Be it lazy initialization or lazy computation.
If you don't use mutable, you are in for a world of hurt.
Of course you could use a const_cast, but what if someone does:
static const MyClass Examplar;
And the compiler decides it is a good candidate for Read-Only memory ? Well, in this case the effects of the const_cast are undefined. At best, nothing happens.
If you still wish to pursue the const_cast route, do it as R Samuel Klatchko do.
If you thought over and think there is likely a better alternative, you can decide to wrap your variable. If it was in class of its own, with only 3 methods: get, set and load_from_database, then you would not worry about it being mutable.
You are basically implementing a caching mechanism. Personally I think it's OK to mark cached data as mutable.
As Matthieu already pointed out, what you're trying to do here has little (if anything) to do with RAII. Likewise, I doubt that any combination of const and mutable is really going to help. const and mutable modify the type, and apply equally to all access to an object of that type.
What you seem to want is for a small amount of code to have write access, and anything else only read access to the value. Given the basic design of C++ (and most similar languages), the right way to do that is to move the variable into a class of its own, with the small amount of code that needs write access as part of (or possibly a friend of) that class. The rest of the world is given its read-only access via the class' interface (i.e., a member function that retrieves the value).
The (presumably stripped down) MyClass you've posted is pretty close to right -- you just need to use that by itself, instead of as part of a larger class with lots of other members. The main things to change would be 1) the name from MyClass to something like lazy_int, and 2) (at least by my preference) get_value() should probably be renamed to operator int(). Yes, m_value will probably need to be mutable, but this doesn't allow other code to write the value, simply because other code doesn't have access to the value itself at all.
Then you embed an object of that type into your larger class. The code in that outer class can treat it as an int (on a read-only basis) thanks to its operator int(), but can't write it, simply because the class doesn't give any way to do so.
[ LOOK MA! NO CASTS! :)) ]
struct DBValue
{
int get_value();
private:
void load_from_database();
int value;
};
struct MyClass
{
MyClass(): db_value(new DBValue()) {}
~MyClass() { delete db_value; }
int get_value() const;
private:
DBValue * const db_value;
};
int MyClass::get_value() const
{
return db_value->get_value(); // calls void load_from_database() if needed
}
The idea is to have a politically correct MyClass with const methods not mutating anything but calling both const and non-const methods of aggregated objects via const pointers.
Don't use const_cast here, or you're asking for trouble. Using mutable in this case shouldn't be a problem, but if the profiler didn't suggest otherwise then I think users would be less surprised to see an object that is expensive to construct than an accessor method that is expensive to call the first time.
If your method changes the state of the object (e.g. by changing the state of the underlying database), then the method should not be const. In that case you should have a separate, non-const load-method, that has to be called before the const getter can be called.
This method would require neither const_cast not mutable, and would make the potentially expensive operation explicit.
is it possible to re-initialize an object of a class using its constructor?
Sort of. Given a class A:
A a;
...
a = A();
the last statement is not initialisation, it is assignment, but it probably does what you want.
Literally? Yes, by using placement new. But first you have to destruct the previously constructed object.
SomeClass object(1, 2, 3);
...
object.~SomeClass(); // destruct
new(&object) SomeClass(4, 5, 6); // reconstruct
...
// Final destruction will be done implicitly
The value of this does not go beyond purely theoretical though. Don't do it in practice. The whole thing is ugly beyond description.
It's possible, although it's a very bad idea. The reason why is that without calling the destructors on the existing object, you are going to leak resources.
With that major caveat, if you insist on doing it, you can use placement new.
// Construct the class
CLASS cl(args);
// And reconstruct it...
new (&cl) CLASS(args);
In C++11, you can do this:
#include <type_traits>
template <class T, typename... Args>
void Reconstruct(T& x, Args&&... args)
{
static_assert(!std::has_virtual_destructor<T>::value, "Unsafe");
x.~T();
new (&x) T(std::forward<Args>(args)...);
}
This allows you to use Reconstruct passing arbitrary constructor parameters to any object. This can avoid having to maintain a bunch of Clear methods, and bugs that can easily go unnoticed if at some point the object changes, and the Clear method no longer matches the constructor.
The above will work fine in most contexts, but fail horribly if the reference is to a base within a derived object that has a virtual destructor. For this reason, the above implementation prevents use with objects that have a virtual destructor.
Short answer:
No. If part of your object's intended behavior is to be initialized several times, then the best way to implement this is through an accessible initialization method. The constructor of your class can simply defer to this method.
class C1 {
public:
C1(int p1, int p2) {
Init(p1,p2);
}
void Init(int p1, int p2) { ... }
};
Nitpicker corner:
Is there some incredibly evil way to call a constructor in C++ after an object is created? Almost certainly, this is C++ after all. But it's fundamentally evil and it's behavior is almost certainly not defined by the standard and should be avoided.
No, constructors are only called when the object is first created. Write a new method to do it instead.
Edit
I will not acknowledge placement new, because I don't want to have to get a pet raptor for work.
See this comic, but think of the topic on hand...
Yes you can cheat and use placement new.
Note: I do not advice this:
#include <new>
reInitAnA(A& value)
{
value.~A(); // destroy the old one first.
new (&value) A(); // Call the constructor
// uses placement new to construct the new object
// in the old values location.
}
I usually write the following in modern C++ :
SomeClass a;
...
a = decltype(a)();
It may be not the most effective way, as it effectively constructs another object of the same type of a and assigns it to a, but it works in most cases, you don't have to remember the type of a, and it adapts if the type changes.
Instead of destructing and reinitializing as suggested by some of the answers above, it's better to do an assignment like below. The code below is exception safe.
T& reinitialize(int x, int y)
{
T other(x, y);
Swap(other); // this can't throw.
return *this;
}
May-be not what you have in mind, but since you didn't mention what it is for, I suppose one answer would be that you'd do it by controlling scope and program flow.
For example, you wouldn't write a game like this:
initialize player
code for level 1
...
reinitialize player
code for level 2
...
etc
Instead you'd strive for:
void play_level(level_number, level_data) {
Player player; //gets "re-initialized" at the beginning of each level using constructor
//code for level
}
void game() {
level_number = 1;
while (some_condition) {
play_level(level_number, level_data);
++level_number;
}
}
(Very rough outline to convey the idea, not meant to be remotely compilable.)
If you really must do this I strongly encourage creating a reset method for this:
class A
{
...
public:
reset() { *this= A() };
}
The above requires A to be copy and move assignable.
That is because the initial unoptimized version will copy from a temp. However copy elision may remove this step.
The behavior of A::reset() is always well defined. It replace the existing data in a valid A instance with a data from a new one. Of course any sub-class of A will still need to define its own version if you wanted its data re-initialized as well. However, failure to do so does not in and of itself invoke undefined or unspecified behavior. It simply means that only whatever memory A uses for its members will be reset. Even the involvement of virtual functions and/or virtual inheritance doesn't change this. Although the usual caveats of using such things apply.
Raw pointers will not be deleted by the above so they will need to be put into a std::shared_ptr or similar construct so the will self destruct when no longer needed.
While most answers are reinitializing an object in two steps; first, creating an initial object, and second creating another object and swapping it with the first one using placement new, this answer covers the case that you first create a pointer to an empty object and later allocate and construct it:
class c *c_instance; // Pointer to class c
c_instance = new c(arg1, ..., argn) // Allocate memory & call the proper constructor
// Use the instance e.g. c->data
delete c_instance; // Deallocate memory & call the destructor
Yes , it is possible.
If you create a method that returns a new object.
#include "iostream"
class a // initialize class
a getNewA(a object){// Create function to return new a object
a new_object(/*Enter parameters for constructor method*/);
return new_object;
}