Comments (2)
It is a common bug about move constructor and copy assignment operator. In these constructor, std::unique_ptr<T>
member is moved from rhs to lhs, so it is empty in rhs.
In code, AddClass
return a instance of TypeDescriptorBuilder<T>
, it calls move constructor.
// reflect.hpp
template <typename T>
details::TypeDescriptorBuilder<T> AddClass(const std::string &name) {
details::TypeDescriptorBuilder<T> b{name};
return b;
}
Definition of TypeDescriptorBuilder<T>
doesn't implement move constructor, so the default one is called.
// reflect.hpp
template <typename T>
class TypeDescriptorBuilder {
...
private:
RawTypeDescriptorBuilder raw_builder_;
};
Default move ctor of TypeDescriptorBuilder<T>
calls move constructor of RawTypeDescriptorBuilder
.
// reflect.hpp
class RawTypeDescriptorBuilder {
...
RawTypeDescriptorBuilder(RawTypeDescriptorBuilder&& rhs) = default;
RawTypeDescriptorBuilder& operator=(RawTypeDescriptorBuilder&& rhs) = default;
...
private:
std::unique_ptr<TypeDescriptor> desc_{nullptr};
};
Default move ctor of RawTypeDescriptorBuilder
moves std::unique_ptr<TypeDescriptor> desc_
.
Now go back to details::TypeDescriptorBuilder<T> AddClass(const std::string &name)
, after move ctor, the lhs now owns the std::unique_ptr
member, the rhs owns empty.
When the program leaves details::TypeDescriptorBuilder<T> AddClass(const std::string &name)
, the rhs is deleted.
To output the process, modify the code like this:
// reflect.hpp
template <typename V>
TypeDescriptorBuilder &AddMemberVar(const std::string &name, V T::*var) {
std::cout << "AddMemberVar" << std::endl;
raw_builder_.AddMemberVar(name, var);
return *this;
}
// reflect.cpp
RawTypeDescriptorBuilder::~RawTypeDescriptorBuilder() {
std::cout << "~RawTypeDescriptorBuilder()" << std::endl;
std::cout << "(desc_ == nullptr) = " << (desc_ == nullptr) << std::endl;
if(desc_ != nullptr)
Registry::instance().Register(std::move(desc_));
}
The output is
~RawTypeDescriptorBuilder()
(desc_ == nullptr) = 1
AddMemberVar
AddMemberVar
~RawTypeDescriptorBuilder()
(desc_ == nullptr) = 0
Obviously, the fix is
// reflect.cpp
RawTypeDescriptorBuilder::~RawTypeDescriptorBuilder() {
if(desc_ != nullptr)
Registry::instance().Register(std::move(desc_));
}
from cpp-training-season1.
Thanks for reporting this! Were you just running https://github.com/taichi-dev/cpp-training-season1/blob/main/reflection/src/main.cpp?
There's nothing fancy in ~RawTypeDescriptorBuilder()
:
cpp-training-season1/reflection/src/reflect.cpp
Lines 13 to 15 in bfe7b2f
desc_
's address before L14, is it already nullptr
?from cpp-training-season1.
Related Issues (2)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cpp-training-season1.