-
July 9th, 2017, 01:39 PM
#1
[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
-
July 9th, 2017, 03:02 PM
#2
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?
-
July 9th, 2017, 03:50 PM
#3
Re: lazy initialisation with shared pointer
final solution.
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 ?
-
July 10th, 2017, 02:08 AM
#4
Re: lazy initialisation with shared pointer
Great that you managed to get it to work!
How can I mark a thread as SOLVED ?
From menu Thread Tools, use Mark Thread Resolved.
[Done]
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 10th, 2017, 07:01 AM
#5
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?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|