Jump to content
  • Advertisement
Sign in to follow this  
Kambiz

a little C++ Question

This topic is 4591 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In c++ you can write something like this: cout << setprecision(2) << pi << endl; Now think I have a class like this: class C { public: int i; } and I want to be able to write something like this: C c; c << Set_i(10); with the effect c.i=10; How should I define Set_i ??

Share this post


Link to post
Share on other sites
Advertisement
class C
{
public:
int setI(int val){i = val; return i;}
private:
int i;
}

Something like that?
Quote:

C c;
c << Set_i(10);


in this particular case, you have the stream operator overloaded and your code makes no sense to me. It also won't compile because you aren't mentioning what class should call setI at all... it should be c << c.Set_i(10); if you really did want to do that. But your code is jumbled and it doesn't make sense.


I assume you want i to be private so someone can't just do this:

C.i = 10;

However, I would suggest having setI return a bool success or fail (or possibly void and have it throw an exception, though you probably haven't looked into error handling) if it fails to set i.

have a seperate function getI which returns the value.

I assume you want accessor functions (that's what a set and get function for a variable are called) because i has a range of acceptable values. If it does not have a range of acceptable values and can in fact be anything, you don't really need accessor functions (though many people still have them anyway.)

So, I'd actually reccomend this:

class C
{
public:
bool setI(int val){/*make sure val is a valid value, return 0 if it is not*/i = val; return 1;}
int getI(){return i;}
private:
int i;
}

Share this post


Link to post
Share on other sites

struct Set_i {
const int i;
Set_i( int i ) : i(i) { }
};

C & C::operator<<( const Set_i & set ) {
this->i = set.i;
return *this;
}

// Also declare operator<< inside class C





EDIT: this is off topic but,


class Set_i {
const int value;
bool done;
int undo;
public:
friend C & operator<<( C &, Set_i & );
friend C & operator>>( C &, Set_i & );
Set_i( int i ) : i(i), done(false), undo(false) { }
};

C & operator<<( C & c, Set_i & i ) {
if( i.done ) { throw AlreadyApplied( ); }
i.done = true;
i.undo = c.i;
c.i = i.value;
return c;
}

C & operator>>( C & c, Set_i & i ) {
if( !i.done ) { throw NotApplied( ); }
if( c.i != i.undo ) { throw IncorrectState( ); }
i.done = false;
c.i = i.undo;
}

Set_i s(10);

C foo;
foo << s; // Change the value to 10
foo >> s; // Undo the value change.




There are several ways to make this better (for one, making clones of a mutator share their internal state.

Share this post


Link to post
Share on other sites
First you need to define your function to take two parameters, a reference to C and an integer:
C & Set_i(C & c, int i)
{
c.i = i;
return c;
}


Next you need to define a helper type that binds a two-parameter function and its arguments into an object that can itself be the paramter to another function:
class Set_i_helper
{
public:
Set_i_helper(C & (*fn)(C &, int), int i) : func(fn), arg(i) {}
friend C & operator << (C &, const Set_i_helper&);

private:
C & (*func)(C &, int);
int arg;
};


Finally, you can now overload the insertion operator:
C & operator << (C & c, const Set_i_helper & s)
{
return (*s.func)(c, s.arg);
}


[Edit: Note that this version will let you call C c; c << Set_i(10) << Set_i(20); and other combinations, unlike the other options.]

Share this post


Link to post
Share on other sites
A slightly more generic solution might be


#include<iostream>

class C
{
public:
int i;
int j;
int k;
};


template<typename T>
C& operator<<(C& c, T& b)
{
b(c);
return c;
}

template<typename T, typename T1>
class SetMember
{
public:

SetMember(T a, T T1::* Member):Value_(a), pMember_(Member){}

void operator()(C& a)
{
a.*pMember_ = Value_;
}

private:
T Value_;
T T1::* pMember_;
};


template<typename T, typename T1>
SetMember<T, T1> Set_Member(T T1::*pMember, T value)
{
return SetMember<T, T1>(value, pMember);
}



int main()
{
C c;
c << Set_Member(&C::i, 10) << Set_Member(&C::j, 11) << Set_Member(&C::k, 12);
std::cout << c.i << c.j << c.k;
return 0;
}




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!