#include <cstdio>
#include <memory>
using namespace std;
#define KNOTE(fmt, args...) ::printf(fmt "\n", ##args)
class TPerfectCtor : public std::enable_shared_from_this<TPerfectCtor>
{
private:
TPerfectCtor(int i = -1)
: IntValue(i) {
KNOTE("%s@%p: %d", __func__, this, IntValue);
}
TPerfectCtor(const TPerfectCtor& r) = default;
public:
template<typename ... T>
static std::shared_ptr<TPerfectCtor> Create(T&& ... all) {
return std::shared_ptr<TPerfectCtor>(new TPerfectCtor(std::forward<T>(all)...));
}
~TPerfectCtor() {
KNOTE("%s@%p: %d", __func__, this, IntValue);
}
std::shared_ptr<TPerfectCtor> GetItRight() {
return shared_from_this();
}
int IntValue;
};
void TestSharedFromThisPerfectCtor()
{
// std::shared_ptr<TPerfectCtor> c1(new TPerfectCtor()); // compile error
std::shared_ptr<TPerfectCtor> c1 = TPerfectCtor::Create(); // TPerfectCtor: -1
std::shared_ptr<TPerfectCtor> c2 = TPerfectCtor::Create(2); // TPerfectCtor: 2
c2 = c1->GetItRight(); // ~TPerfectCtor: 2
KNOTE("c1 use count: %lu", c1.use_count()); // 2
KNOTE("c2 use count: %lu", c2.use_count()); // 2
}
// ~TPerfectCtor: -1
int main()
{
TestSharedFromThisPerfectCtor();
return 0;
}
I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPG1lbW9yeT4KIAp1c2luZyBuYW1lc3BhY2Ugc3RkOwogCiNkZWZpbmUgS05PVEUoZm10LCBhcmdzLi4uKSA6OnByaW50ZihmbXQgIlxuIiwgIyNhcmdzKQoKY2xhc3MgVFBlcmZlY3RDdG9yIDogcHVibGljIHN0ZDo6ZW5hYmxlX3NoYXJlZF9mcm9tX3RoaXM8VFBlcmZlY3RDdG9yPgp7CnByaXZhdGU6CiAgVFBlcmZlY3RDdG9yKGludCBpID0gLTEpCiAgICA6IEludFZhbHVlKGkpIHsKICAgIEtOT1RFKCIlc0AlcDogJWQiLCBfX2Z1bmNfXywgdGhpcywgSW50VmFsdWUpOwogIH0KICBUUGVyZmVjdEN0b3IoY29uc3QgVFBlcmZlY3RDdG9yJiByKSA9IGRlZmF1bHQ7CgpwdWJsaWM6CiAgdGVtcGxhdGU8dHlwZW5hbWUgLi4uIFQ+CiAgc3RhdGljIHN0ZDo6c2hhcmVkX3B0cjxUUGVyZmVjdEN0b3I+IENyZWF0ZShUJiYgLi4uIGFsbCkgewogICAgcmV0dXJuIHN0ZDo6c2hhcmVkX3B0cjxUUGVyZmVjdEN0b3I+KG5ldyBUUGVyZmVjdEN0b3Ioc3RkOjpmb3J3YXJkPFQ+KGFsbCkuLi4pKTsKICB9CgogIH5UUGVyZmVjdEN0b3IoKSB7CiAgICBLTk9URSgiJXNAJXA6ICVkIiwgX19mdW5jX18sIHRoaXMsIEludFZhbHVlKTsKICB9CiAgc3RkOjpzaGFyZWRfcHRyPFRQZXJmZWN0Q3Rvcj4gR2V0SXRSaWdodCgpIHsKICAgIHJldHVybiBzaGFyZWRfZnJvbV90aGlzKCk7CiAgfQogIGludCBJbnRWYWx1ZTsKfTsKCnZvaWQgVGVzdFNoYXJlZEZyb21UaGlzUGVyZmVjdEN0b3IoKQp7CiAgLy8gc3RkOjpzaGFyZWRfcHRyPFRQZXJmZWN0Q3Rvcj4gYzEobmV3IFRQZXJmZWN0Q3RvcigpKTsgLy8gY29tcGlsZSBlcnJvcgogIHN0ZDo6c2hhcmVkX3B0cjxUUGVyZmVjdEN0b3I+IGMxID0gVFBlcmZlY3RDdG9yOjpDcmVhdGUoKTsgLy8gVFBlcmZlY3RDdG9yOiAtMQogIHN0ZDo6c2hhcmVkX3B0cjxUUGVyZmVjdEN0b3I+IGMyID0gVFBlcmZlY3RDdG9yOjpDcmVhdGUoMik7IC8vIFRQZXJmZWN0Q3RvcjogMgogIGMyID0gYzEtPkdldEl0UmlnaHQoKTsgIC8vIH5UUGVyZmVjdEN0b3I6IDIKICBLTk9URSgiYzEgdXNlIGNvdW50OiAlbHUiLCBjMS51c2VfY291bnQoKSk7IC8vIDIKICBLTk9URSgiYzIgdXNlIGNvdW50OiAlbHUiLCBjMi51c2VfY291bnQoKSk7IC8vIDIKfQovLyB+VFBlcmZlY3RDdG9yOiAtMQoKaW50IG1haW4oKQp7ClRlc3RTaGFyZWRGcm9tVGhpc1BlcmZlY3RDdG9yKCk7CnJldHVybiAwOwp9