Forum Replies Created
- AuthorPosts
- ::
Right, OK, but in your example with the unique_ptr you used make_unique to construct a new unique_ptr to a DefaultWindow, then passed it in to the createWindow function which takes the base class as argument and uses polymorphism to call the correct create() function on the DefaultWindow class.
My point was just that you already created a unique_ptr to the DefaultWindow, then used that to request creation of pointer to a new instance from the factory.
In the other examples, you created a stack allocated version, and used the factory to create a pointer to a new heap allocated DefaultWindow
It looked like the factory wasn’t needed in these cases?
17. February 2023 at 11:17 in reply to: Finding out the type of a polymoprphic type without using dynamic_cast #461797::Yeah, that does sound a more robust solution.
In this case the files aren’t opened in their constructor, they are passed to an async job which opens reads/writes then closes. I suppose a better method might be to pass the filename, so the async job can as you say, then construct and destruct the file resource.
::I would test it in two ways, firstly internal unit tests, these will need access to the library’s source files so that it can call internal functions. So you’d compile the test code with the internal code of the library (but not make it a part of the library)
Secondly, integration or subsystem tests, which test the public interface of your library. These tests will call the library’s interface functions by linking to the library dll (with no knowledge of the internal implementation) so that you can test the library’s expected functionality. You may need to mock certain aspects of the system to test like this, but that’s where your design should separate those bits out to make testing easier (extracting common data types out to easily accessible headers etc).
::If you want to use pointers for practice that’s cool 🙂 and there’s nothing ‘wrong’ with using them in this case.
I do have that book, it’s in my pile to read, I haven’t worked through it yet. I would probably do the same as you and use C++, translating from Ruby is a little weird.
Would be good to hear your opinions on the book when you’re done.
::Here is a modified version I played with that creates a local Grid myGrid, in main(), and passes that grid into the make_grid and init_grid by reference.
https://godbolt.org/z/PabbYGvqo
Init grid uses the vector subscripting to find the neighbours, because we know that grid[1,0] is to the west of grid[1,1]. We just need to check for the boundary cells, because they have no neighbours on one side.
It has an operator<< to help with printing out a Cell. ( std::cout << cell; )
Do you need to store a pointer to the neighbours? You already know where they are using the vector subscripts? If you really need to you could have member functions in Cell like get_west(r,c) to return the cell address of the cell to the west of cell r,c, but all it would do is return a reference to grid[r, c – 1]; I could imagine using pointers to neighbours if you wanted to change neighbours – perhaps you have tunnels or bridges to other neighbours 🙂 or secret vents to other cells, then you’d change the pointer.
We don’t even really need to store the Cells position with row and col. we know where each cell is 🙂
In your original sample, you built the grid then copied it back in the return. With a local copy, passed in by reference everywhere, there are no extra copies.
The Cell class has a bunch of raw pointers, which will only get shallow copied in the Cell copy constructor. Turns out the Cell only gets copied during make_grid, and the pointers don’t have values at that point, so it works OK, but this is a source of possible future bugs! 🙂 Much better would be to disable the copy constructor/copy assignment member functions and construct manually in place when required, or have a user defined copy constructor/assignment operator that does deep copies, but we don’t even need to copy yet anyway.
::The videos in the Further Information in the ‘Optimisation’ and ‘Correctness’ sections have the same issues:
::You can make it read-only too, after you click share on godbolt.org
struct MySuspendNever { MySuspendNever(std::chrono::duration<double, std::milli> sleep): sleepDuration(sleep) {} std::chrono::duration<double, std::milli> sleepDuration; bool await_ready() const noexcept { std::cout << " MySuspendNever::await_ready" << '\n'; std::this_thread::sleep_for(sleepDuration); return true; } void await_suspend(std::coroutine_handle<>) const noexcept { std::cout << " MySuspendNever::await_suspend" << '\n'; } void await_resume() const noexcept { std::cout << " MySuspendNever::await_resume" << '\n'; } };
struct promise_type { auto get_return_object() { return Job{handle_type::from_promise(*this)}; } std::suspend_always initial_suspend() { std::cout << " Job prepared" << '\n'; return {}; } std::suspend_always final_suspend() noexcept { std::cout << " Job finished" << '\n'; return {}; } void return_void() {} void unhandled_exception() {} };
::If execution of this thread, the one that created the lambda waits inside done.WaitForDoneSignal(), is that OK? Because then done cannot go out of scope until the signal is received from the lambda, it will wait indefinitely for the signal.
It’s still possible to get a dead lock if the connection fails, but will the borrowed variables still be in scope?
If done was taken by value then it could not trigger the signal in the scope of done.
23. June 2022 at 21:09 in reply to: ModernesCpp blog post query about string max_size() vs vector max_size() #54307 - AuthorPosts