Skip to content

Instantly share code, notes, and snippets.

@codecurve
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codecurve/74cf2ecd6cad9b625866 to your computer and use it in GitHub Desktop.
Save codecurve/74cf2ecd6cad9b625866 to your computer and use it in GitHub Desktop.
One-to-many pattern in C++ 11 - Exploring std::reference_wrapper in the context of a pattern for a one-to-many relationship with ownership in C++. (See http://codereview.stackexchange.com/a/63821/53507)
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <string>
#include <iostream>
using namespace std;
class Question;
class User
{
public:
~User();
void ask( Question& question )
{
questions.push_back( question );
}
void unAsk( const Question& question );
const std::vector< std::reference_wrapper<Question> >& getQuestions( void ) const;
std::vector< std::reference_wrapper<Question> >& getQuestions( void );
protected:
std::vector< std::reference_wrapper< Question > > questions;
};
class Question
{
public:
Question( User& user, int id ) : id(id), user( user ){ user.ask( *this ); }
~Question();
void invalidate() {valid = false;}
std::string text;
const std::string getText() const {
return text;
}
bool isEqual(const Question& q) const {
return id == q.id;
}
protected:
int id;
User& user;
bool valid = true;
};
Question::~Question( void )
{
user.unAsk( *this );
}
User::~User( void )
{
for ( auto& question: questions ) {
question.get().invalidate();
}
}
void User::unAsk( const Question& question )
{
//Something like this: remove_if(questions.begin(), questions.end(), [question](const Question& q) {return q.isEqual(question);});
//Commented out the above line, wasn't very pertinent to question being explored, and it seems I'm making some silly mistake, so it isn't working.
}
const std::vector< std::reference_wrapper<Question> >& User::getQuestions( void ) const
{
return questions;
}
std::vector< std::reference_wrapper<Question> >& User::getQuestions( void )
{
return questions;
}
void function1( const User& user )
{
user.getQuestions()[0].get().text = "should not be able to to edit question"; // compile error
}
void anotherFunction( User& user )
{
user.getQuestions()[0].get().text = "edit question"; // just fine
}
int main(int argc, const char * argv[]) {
User u1;
Question q1(u1,1);
q1.text = "What is 6 times 7 ?";
anotherFunction(u1);
function1(u1);
cout << q1.getText() << endl;
u1.unAsk(q1);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment