I somehow read that it is bad style to do object-creation in a constructor ... however, I forgot why it was considered to be bad style (especially when using dependency injection).
Here an example of object-creation in the constructor as pseudo-code:
Myclass
{
Myclass(MyMemberFactory& fac)
{
for(Some criteria)
push_back(fac.createMyMemberType());
}
vector<MyMemberType*> getMyMember();
{
return myMember_;
}
...
private:
vector<MyMemberType*> myMember_;
}
So you can use unit-testing without problems, because you can mock-away the MyMemberFactory.
If I would move the for-loop in an seperated initialize-method, it would be necesarry to check for double-initialisation, and all getters would need first to ckeck, if initialisation already was done. Here the code, by using a seperate initialisation:
Myclass
{
Myclass() : isInitialized_(false)
{
}
void initialize(MyMemberFactory& fac);
{
if(isInitialized_)
throw "Error: Double-Init is not permitted.";
for(Some criteria)
push_back(fac.createMyMemberType());
isInitialized_ =true;
}
vector<MyMemberType*> getMyMember();
{
if(isInitialized_)
throw "Initialize first!";
return myMember_;
}
...
private:
vector<MyMemberType*> myMember_;
bool isInitialized_;
}
So do know any reason, why I should use the second approach over the first approach? Or maybe I just had something wrong in mind, and the first approach is perfectly ok?
If the constructor throws an exception, the destructor will not be called, thus you will lose all the memory that you manually allocated.
The first approach is actually fine. It's not that object creation in a constructor is problematic, it's that doing so with a constructor is problematic. So
Myclass()
{
MyMemberFactory fac;
for(Some criteria)
push_back(fac.createMyMemberType());
}
Would be problematic since clients can no longer use a different factory (for testing, for instance).
Related
I'm trying to create a constructor in which the strings are dynamically allocated. I've looked up dynamically allocated memory several times and watched a video about it, but I'm still not 100% sure if I'm understanding the concept. I'm hoping an example specific to what I'm coding will help me out a bit.
These are the private variables I have in my h file:
string* tableID;
int numSeats;
string* serverName;
With that in mind, could someone tell me how I could dynamically allocate memory for the strings in this constructor?
Table::Table(const string& tableID, int numSeats, const string& serverName) {
}
Finally, I would greatly appreciate it if someone could tell me the purpose of dynamically allocated memory. I've see explanations on what dynamically allocate memory is, but I'm not understanding the use of it. Why use dynamically allocated memory? What are the benefits? What are the drawbacks? Thank you!
EDIT: I'm including the rest of the h file. Note that this wasn't created by me, so I can't make changes to it. I can only adhere to it in the cpp file.
#include <string>
#include "party.h"
using std::string;
class Table {
public:
Table();
Table(const string& tableID, int numSeats, const string& serverName);
~Table();
const string* getTableID() const { return tableID; }
int getNumSeats() const { return numSeats; }
const string* getServerName() const { return serverName; }
void decrementTimer() { timer--; }
int getTimer() const { return timer; }
void setTimer(int duration) { timer = duration; }
const Party* getParty() { return party; }
void seatParty(const Party* newParty);
void clearTable() { party = nullptr; timer = 0; }
private:
string* tableID;
int numSeats;
string* serverName;
int timer;
const Party* party;
};
The easiest way to get what you want is to take advantage of the Member Initializer List as this also solves the problem of having the parameters shadow the member variables of the same name.
Table::Table(const string& tableID,
int numSeats,
const string& serverName):
tableID(new string(tableID)),
numSeats(numSeats),
serverName(new string(serverName))
{
}
Allocation is performed with the new operator. Later you will have to release the dynamically allocated memory with the delete operator. Here is documentation on new and the same for delete.
But the use a pointer requirement is bizarre as storing pointers to string makes everything else you with the class do orders of magnitude more difficult. This may be the point of the assignment, but there are better and less-confusing ways to teach this lesson.
The allocated strings must be released. The C++ idiom of Resource Allocation Is Initialization (What is meant by Resource Acquisition is Initialization (RAII)?) suggests you have a destructor to automate clean-up to ensure that it is done. If you need a destructor, you almost always need the other two members of The Big Three (What is The Rule of Three?) and possibly need to take The Rule of Five into account as well.
Whereas because string observes the Rule of Five for you, you should be able to take advantage of the Rule of Zero and implement no special functions.
M.M raises an excellent point in the comments. The above example is too naive. It is probably all you need for the assignment, but it's not good enough for real code. Sooner or later it will fail. Example of how it fails.
First we replace string with something that can expose the error:
class throwsecond
{
static int count;
public:
throwsecond(const string &)
{
if (count ++)
{
count = 0; // reset count so only every second fails
throw runtime_error("Kaboom!");
}
cout << "Constructed\n";
}
~throwsecond()
{
cout << "Destructed\n";
}
};
int throwsecond::count = 0;
Then a simple class that does basically the above with less frills
class bad_example
{
throwsecond * a;
throwsecond * b;
public:
bad_example(): a(nullptr), b(nullptr)
{
}
bad_example (const string& a,
const string& b)
{
this->a = new throwsecond(a);
this->b = new throwsecond(b);
}
~bad_example()
{
delete a;
delete b;
}
};
and a main to exercise it
int main()
{
cout << "Bad example\n";
try
{
bad_example("", "");
}
catch (...)
{
cout << "Caught exception\n";
}
}
Output:
Bad example
Constructed
Caught exception
We have an object constructed and never destroyed.
Since a default constructor has been defined by Table we can, with a compiler that supports the C++11 or a more recent Standard, take advantage of delegated constructors to force destruction of the partially constructed object because it has been fully constructed by the default constructor.
class good_example
{
throwsecond * a;
throwsecond * b;
public:
good_example():
a(nullptr), b(nullptr) //must be nulled or destruction is dicey
{
}
good_example (const string& a,
const string& b) : good_example() // call default constructor
{
this->a = new throwsecond(a);
this->b = new throwsecond(b);
}
~good_example()
{
delete a;
delete b;
}
};
Output:
Good example
Constructed
Destructed
Caught exception
One construct and one destruct. The beauty of this approach is it scales well and adds nothing to the code that you don't already have. The cost is minimal, a and b get initialized and then assigned as opposed to just initialization. Faster code is useless if it doesn't work.
Full example: https://ideone.com/0ckSge
If you can't compile to a modern standard, you wind up doing something like
the next snippet to make sure everything is deleted. It's main sin is it's ugly, but as you add more classes that must be constructed and destroyed it starts getting unwieldy.
Table::Table(const string& tableID,
int numSeats,
const string& serverName):
tableID(NULL),
numSeats(numSeats),
serverName(NULL)
{
try
{
this->tableID(new string(tableID)),
// see all the this->es? don't shadow variables and you won't have this problem
// miss a this-> and you'll have a really bad day of debugging
this->serverName(new string(serverName))
// more here as required
}
catch (...)
{
delete this->tableID;
delete this->serverName;
// more here as required
throw;
}
}
There is probably a way to improve on this and make it more manageable, but I don't know it. I just use newer standards and value semantics (I'd love it if someone can provide a good link that describes this concept) where possible.
I needed to use some class today that followed this basic design:
class Task {
public:
Task() {
Handler::instance().add(this);
}
virtual void doSomething() = 0;
};
class Handler {
std::vector<Task*> vec;
//yea yea, we are locking the option to use default constructor etc
public:
static Handler& instance() {
static Handler handler;
return handler;
}
void add(Task* task) {
vec.push_back(task);
}
void handle() {
for (auto t : vec) {
t->doSomething();
}
}
};
template <class T, int SIZE>
class MyTask : public Task {
T data[SIZE];
public:
virtual void doSomething() {
// actually do something
}
};
//somewhere in the code:
Handler::instance().handle();
now, my class is something like
class A {
MyTask<bool, 128> myTask;
public:
A(int i) {}
};
the way I wanted to do it is having a map where instances of A are values
static std::map<int, A> map = {
{42, A(1948)},
{88, A(-17)}
};
first to clarify something - this code needs to run on a real time embedded system so I'm not allowed to allocate memory using new for several legacy reasons.
My problem was that the actual objects in the map weren't the ones I explicitly created and so they didn't register in the Handler class (so I didn't get the benefit of the Handler::handle calls).
I tried figuring a nice way to solve this without doing something ugly like first creating an array of A then only point to these objects in the map for example.
I never used move semantics before but I've read little bit about them and thought they can be my solution.
however, after reading this answer (specificaly the very first example) it seemed that I can't really benefit anything from using move semantics.
I tried it anyway (coz why the heck not...) and did something like this instead:
static std::map<int, A> map = {
{42, std::move(A(1948))},
{88, std::move(A(-17))}
};
now for my surprise the copy constructor of MyTask was still called (I put print in it to verify) but for some reason now the handler registration worked well and my instances enjoyed the doSomething() calls.
I tried reading more thoroughly about std::move to understand what exactly happened there but couldn't find the answer.
can anyone explain it? does std::move moves the this pointer somehow? or maybe it just caused the registration to happen correctly somehow and had nothing real to do with the moving attempt
thanks
edit:
to further clarify what I'm asking:
I understand the use of std::move was not contributing to what's being done there.
But for some reason it did get my objects in the map to get the doSomething() calls through the handler. I'm looking for that reason
on a side note as it probably belongs to a different question - is there any decent way to initialize a map this way without the overhead of creating each object twice?
Your question has a lot more in it than it needs to but I think I understand the root question here. The std::map constructor receives an initialization_list, you're calling (5) from this list. Objects are copied out of an initializer_list when iterating over it rather than moved because a copy of an initializer_list doesn't copy the underlying objects. The same affects other std containers, here is an example with vector to demonstrate. (live link)
#include <vector>
#include <iostream>
struct Printer {
Printer() { std::cout << "default ctor\n"; }
Printer(const Printer&) { std::cout << "copy\n"; }
Printer(Printer&&) { std::cout << "move\n"; }
};
int main() {
std::vector<Printer> v = {Printer{}};
}
if you use {std::move(Printer{})} you'll add another move into the mix that the compiler can't easily get optimize away.
I have the following code:
class ClassA
{
public:
ClassA(std::string str);
std::string GetSomething();
};
int main()
{
std::string s = "";
try
{
ClassA a = ClassA(s);
}
catch(...)
{
//Do something
exit(1);
}
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
I would like the last line could access the a variable. How could I achieve that, given ClassA doesn't have default constructor ClassA() and I would not like to use pointers? Is the only way to add a default constructor to ClassA?
You can't or shouldn't. Instead you could just use it within the try block, something like:
try
{
ClassA a = ClassA(s);
std::string result = a.GetSomething();
}
catch(...)
{
//Do something
exit(1);
}
The reason is that since a goes out of scope after the try block referring to the object after that is undefined behavior (if you have a pointer to where it were).
If you're concerned with a.GetSomething or the assignment throws you could put a try-catch around that:
try
{
ClassA a = ClassA(s);
try {
std::string result = a.GetSomething();
}
catch(...) {
// handle exceptions not from the constructor
}
}
catch(...)
{
//Do something only for exception from the constructor
exit(1);
}
You can use some sort of optional or just use std::unique_ptr.
int main()
{
std::string s = "";
std::unique_ptr<ClassA> pa;
try
{
pa.reset(new ClassA(s));
}
catch
{
//Do something
exit(1);
}
ClassA& a = *pa; // safe because of the exit(1) in catch() block
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
Of course, just extending the try block to include the usage of a is the simplest solution.
Also, if you were really planning to exit(1) or otherwise abort the program on failure then simply don't put a try block here at all. The exception will propagate up, aborting the program if it is not caught .
One alternative is to use std::optional . This is the same sort of concept as using a pointer, but it uses automatic allocation and so you are less likely to create a memory leak. This is currently experimental status; you can use boost::optional instead if your compiler doesn't have std::experimental::optional:
#include <experimental/optional>
using std::experimental::optional;
using std::experimental::in_place;
// ...
optional<ClassA> a;
try
{
a = optional<ClassA>(in_place, s);
}
catch(...)
{
// display message or something
}
std::string result;
if ( a )
result = a->GetSomething();
I'd like to reiterate though that this is a bit of a spaghetti style and it'd be better to design your code differently so you aren't continually testing whether construction succeeded or failed.
This requires ClassA be movable or copyable. The in_place is a special argument which invokes a perfect forwarding constructor for the remaining arguments. Without in_place you can only give an actual ClassA as constructor argument, it doesn't consider implicit conversions to ClassA. (This is how optional avoids the ambiguity between copy-construction and list-initialization from object of the same type).
I have a class that holds a large table of data, with a constructor that takes all of the parameters needed to calculate that data. However, it takes a long time to run, so I've added a constructor that takes a stream, and reads the data in from that stream. I'm having trouble coming up with a RAII way of designing this class though, since I have two constructors, and at run time I need to choose between them. This is what I've come up with:
std::string filename; // Populated by command line arguments
DataTable table; // Empty constructor, no resource acquisition or initialization
if( filename.empty() ) {
table = DataTable(/*various parameters*/);
} else {
std::ifstream filestream(filename);
table = DataTable(filestream); // Reads from file
}
That looks pretty fragile to me. The default constructor will leave the object in a valid state, but a useless one. The only use of it is to create a "temporary" object in the outer scope, to be assigned to in one of the branches of the if statement. Additionally, there's a flag "inited" behind the scenes to manage if the object was default-constructed or fully initialized. Is there a better way to design this class?
Maybe like this:
DataTable foo = filename.empty()
? DataTable(x, y, z)
: DataTable(std::ifstream(filename));
Move the file test code that decides which way to init into the ctor, move the ctors into two private init functions, call one of these from the ctor or throw an exception if everything fails.
Some thoughts:
Get rid of the "inited" flag.
Get rid of the default constructor if it can't sensibly construct the object
use this kind of construct to get you a DataTable:
DataTable get_me_my_data_fool(ParameterTypes... params, const string& filename = "")
{
if(!filename.empty())
return DataTable(std::ifstream(filename)); // check if file exists!
else
return DataTable(params...);
}
Actually, now that I think about it, it would be better to just put this logic into the DataTable constructor.
If the class supports copy, then Kerrek SB's solution is the way
to go. From what you say, however, copying is expensive. In
that case, and you can use C++11, you might try adding a move
constructor, in order to avoid the deep copy. Otherwise, you're
probably stuck allocating dynamically:
std::auto_ptr<DataTable> fooPtr( filename.empty()
? new DataTable( x, y z )
: new DataTable( filename ) );
DataTable& foo = *fooPtr;
Here's another idea for completeness sake:
template<typename T>
class uninitialised
{
public:
~uninitialised()
{
if (alive_) {
operator T&().~T();
}
}
template<typename... Ts>
void create(Ts&&... args)
{
assert(!alive_ && "create must only be called once");
void* const p = obj_;
::new(p) T(std::forward<Ts>(args)...);
alive_ = true;
}
operator T&()
{
assert(alive_ && "T has not been created yet");
return *reinterpret_cast<T*>(obj_);
}
private:
bool alive_ = false;
alignas(T) unsigned char obj_[sizeof(T)];
};
// ...
std::string filename;
uninitialised<DataTable> table;
if (filename.empty()) {
table.create(/* various parameters */);
} else {
std::ifstream filestream(filename);
table.create(filestream);
}
DataTable& tbl = table;
I just got burned by a bug that is partially due to my lack of understanding, and partially due to what I think is suboptimal design in our codebase. I'm curious as to how my 5-minute solution can be improved.
We're using ref-counted objects, where we have AddRef() and Release() on objects of these classes. One particular object is derived from the ref-count object, but a common function to get an instance of these objects (GetExisting) hides an AddRef() within itself without advertising that it is doing so. This necessitates doing a Release at the end of the functional block to free the hidden ref, but a developer who didn't inspect the implementation of GetExisting() wouldn't know that, and someone who forgets to add a Release at the end of the function (say, during a mad dash of bug-fixing crunch time) leaks objects. This, of course, was my burn.
void SomeFunction(ProgramStateInfo *P)
{
ThreadClass *thread = ThreadClass::GetExisting( P );
// some code goes here
bool result = UseThreadSomehow(thread);
// some code goes here
thread->Release(); // Need to do this because GetExisting() calls AddRef()
}
So I wrote up a little class to avoid the need for the Release() at the end of these functions.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * Thread() const { return m_T; }
};
So that now I can just do this:
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC.Thread());
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}
What I don't like is that to access the thread pointer, I have to call a member function of ThreadContainer, Thread(). Is there some clever way that I can clean that up so that it's syntactically prettier, or would anything like that obscure the meaning of the container and introduce new problems for developers unfamiliar with the code?
Thanks.
use boost::shared_ptr
it is possible to define your own destructor function, such us in next example: http://www.boost.org/doc/libs/1_38_0/libs/smart_ptr/sp_techniques.html#com
Yes, you can implement operator ->() for the class, which will recursively call operator ->() on whatever you return:
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
ThreadClass * operator -> () const { return m_T; }
};
It's effectively using smart pointer semantics for your wrapper class:
Thread *t = new Thread();
...
ThreadContainer tc(t);
...
tc->SomeThreadFunction(); // invokes tc->t->SomeThreadFunction() behind the scenes...
You could also write a conversion function to enable your UseThreadSomehow(ThreadContainer tc) type calls in a similar way.
If Boost is an option, I think you can set up a shared_ptr to act as a smart reference as well.
Take a look at ScopeGuard. It allows syntax like this (shamelessly stolen from that link):
{
FILE* topSecret = fopen("cia.txt");
ON_BLOCK_EXIT(std::fclose, topSecret);
... use topSecret ...
} // topSecret automagically closed
Or you could try Boost::ScopeExit:
void World::addPerson(Person const& aPerson) {
bool commit = false;
m_persons.push_back(aPerson); // (1) direct action
BOOST_SCOPE_EXIT( (&commit)(&m_persons) )
{
if(!commit)
m_persons.pop_back(); // (2) rollback action
} BOOST_SCOPE_EXIT_END
// ... // (3) other operations
commit = true; // (4) turn all rollback actions into no-op
}
I would recommend following bb advice and using boost::shared_ptr<>. If boost is not an option, you can take a look at std::auto_ptr<>, which is simple and probably addresses most of your needs. Take into consideration that the std::auto_ptr has special move semantics that you probably don't want to mimic.
The approach is providing both the * and -> operators together with a getter (for the raw pointer) and a release operation in case you want to release control of the inner object.
You can add an automatic type-cast operator to return your raw pointer. This approach is used by Microsoft's CString class to give easy access to the underlying character buffer, and I've always found it handy. There might be some unpleasant surprises to be discovered with this method, as in any time you have an implicit conversion, but I haven't run across any.
class ThreadContainer
{
private:
ThreadClass *m_T;
public:
ThreadContainer(Thread *T){ m_T = T; }
~ThreadContainer() { if(m_T) m_T->Release(); }
operator ThreadClass *() const { return m_T; }
};
void SomeFunction(ProgramStateInfo *P)
{
ThreadContainer ThreadC(ThreadClass::GetExisting( P ));
// some code goes here
bool result = UseThreadSomehow(ThreadC);
// some code goes here
// Automagic Release() in ThreadC Destructor!!!
}