[RESOLVED] lazy initialisation with shared pointer
Hi
I am trying to introduce a lazy initialisation using a shared pointer.
The function that performs the initialisation is a public member function and uses a lambda.
I am unsure if the lambda is correct though. A compile error is generated on the code (below).
A small subset of the code looks something like this:
Code:
#include <iostream>
#include <memory>
#include <string>
#include <mutex>
class Member;
using sharep = std::shared_ptr<Member>;
class Member {
private:
std::string sname;
int sage{0};
std::once_flag once_flag;
public:
Member(const std::string & name, int age) : sname{name}, sage{age} { }
Member() {}
Member ( const Member & ) = delete; // avoid copy
~Member() {}
void init_profile(const std::string & name, const int age) {
sname = name;
}
const std::string view_profile() const {
return "Name : " + sname + ", age: " + std::to_string(sage) ;
}
void init(sharep & sptr, const std::string & name, const int age ) {
std::call_once(once_flag, [](sharep & sptr){ if(!sptr) { sptr.reset(new Member);} } );
sptr->init_profile(name, age);
}
};
int main() {
sharep sptr;
sptr.init(sptr, "Harry Potter", 12);
std::cout << "Profile : " << sptr->view_profile() << "\n";
return 0;
}
The compile error generated is on line 40:
Code:
error: ‘using sharep = class std::shared_ptr<Member> {aka class std::shared_ptr<Member>}’ has no member named ‘init’
Can anybody suggest where the code needs fixing?
Thanks
Re: lazy initialisation with shared pointer
quick, update, I'm a bit further to a solution by modifying the code to the following:
Code:
#include <iostream>
#include <memory>
#include <string>
#include <mutex>
class Member;
using sharep = std::shared_ptr<Member>;
class Member {
private:
std::string sname;
int sage{0};
std::once_flag once_flag; // std::once_flag cannot be copied or moved
public:
Member(const std::string & name, int age) : sname{name}, sage{age} { }
Member() {}
Member ( const Member & ) = delete; // avoid copy
~Member() {}
void init_profile(const std::string & name, const int age) {
sname = name; sage = age;
}
const std::string view_profile() const {
return "Name : " + sname + ", age: " + std::to_string(sage);
}
void init(sharep & sptr, const std::string & name, const int age ) {
std::call_once(once_flag, [/*sharep*/ & sptr](){ if(!sptr) sptr.reset(new Member); } ) ;
sptr->init_profile(name, age);
}
};
int main() {
sharep sptr;
sptr->init(sptr, "Harry Potter", 12);
std::cout << "Profile : " << sptr->view_profile() << "\n";
return 0;
}
But now a segmentation fault occurs instead. Any suggestions as to what the reason is?
Re: lazy initialisation with shared pointer
final solution.:d
Code:
#include <iostream>
#include <memory>
#include <string>
#include <mutex>
class Member;
using sharep = std::shared_ptr<Member>;
class Member {
private:
std::string sname;
int sage{0};
std::once_flag once_flag; // std::once_flag cannot be copied or moved
public:
Member(const std::string & name, int age) : sname{name}, sage{age} { }
Member() {}
Member ( const Member & ) = delete; // avoid copy
~Member() {}
void init_profile(const std::string & name, const int age) {
sname = name; sage = age;
}
const std::string view_profile() const {
return "Name : " + sname + ", age: " + std::to_string(sage);
}
void init(sharep & sptr, const std::string & name, const int age ) {
std::call_once(once_flag, [/*sharep*/ & sptr](){ if(!sptr) sptr.reset(new Member); } ) ;
sptr->init_profile(name, age);
}
};
int main() {
sharep sptr(new Member());
sptr->init(sptr, "Harry Potter", 12);
std::cout << "Profile : " << sptr->view_profile() << "\n";
return 0;
}
How can I mark a thread as SOLVED ?
Re: lazy initialisation with shared pointer
Great that you managed to get it to work! :thumb:
Quote:
How can I mark a thread as SOLVED ?
From menu Thread Tools, use Mark Thread Resolved.
[Done]
Re: [RESOLVED] lazy initialisation with shared pointer
Code:
sharep sptr(new Member());
Doesn't this rather mitigate against the initialisation using a shared pointer as sptr is initialised here?
Consider
Code:
#include <iostream>
#include <memory>
#include <string>
#include <mutex>
class Member;
using sharep = std::shared_ptr<Member>;
std::once_flag member_flag; // std::once_flag cannot be copied or moved
class Member {
private:
std::string sname;
int sage{ 0 };
public:
Member(const std::string & name, int age) : sname{ name }, sage{ age } { }
Member() {}
Member(const Member &) = delete; // avoid copy
void init_profile(const std::string & name, const int age) {
sname = name; sage = age;
}
const std::string view_profile() const {
return "Name : " + sname + ", age: " + std::to_string(sage);
}
void init(sharep& sptr, const std::string & name, const int age) {
std::call_once(member_flag, [&]() {sptr.reset(new Member); });
sptr->init_profile(name, age);
}
};
int main() {
sharep sptr;
sptr->init(sptr, "Harry Potter", 12);
std::cout << "Profile : " << sptr->view_profile() << "\n";
sptr->init(sptr, "James Bond", 37);
std::cout << "Profile : " << sptr->view_profile() << "\n";
return 0;
}
where sptr isn't first initialised but is initialised once when init is first called which I think is what you were trying to achieve?