• Advertisement
Sign in to follow this  

c++ static methods

This topic is 3630 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

Can someone explain to me the reason for using a static method? Aren't all methods of a class static by defualt and shared among all instances of the class? TIA

Share this post


Link to post
Share on other sites
Advertisement
A static function doesn't need an instance of a class/struct to be called on. Example:


struct Foo
{
static void bar() {}
};

int main()
{
Foo::bar();
return 0;
}



One reason you'd use one is that a static method can access private and protected data members and functions, so you could use one for a callback for instance - the function is static, so doesn't need a valid this pointer, and can access all private members of any struct/class of the same type passed in.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
A static function doesn't need an instance of a class/struct to be called on. Example:

*** Source Snippet Removed ***

One reason you'd use one is that a static method can access private and protected data members and functions, so you could use one for a callback for instance - the function is static, so doesn't need a valid this pointer, and can access all private members of any struct/class of the same type passed in.


Of course, you should note the flip side of that: the function doesn't *have* a valid this pointer, so you need to pass in an instance in order to access any members.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Of course, you should note the flip side of that: the function doesn't *have* a valid this pointer, so you need to pass in an instance in order to access any members.
True. I should have been more clear.

An example of how such a callback would work:

// Callback function pointer
typedef void (*LPCallback)(int n, void* pUserData);

// Function that performs a callback:
void SomeFunction(LPCallback pfnCallback, void* pUserData)
{
for(int i=0; i<10; ++i)
pfnCallback(n, pUserData);
}

// Your code to call that:
struct Foo
{
static void Bar(int n, void* pUserData)
{
Foo* pThis = (Foo*)pUserData;
std::cout << pThis->strName << ": " << n << std::endl;
}

std::string strName;
};

// Example:
int main()
{
Foo foo;
foo.strName = "Blah";

SomeFunction(Foo::Bar, &foo);
return 0;
}

That sort of code frequently pops up when dealing with C interfaces (E.g. the Win32 API). If yuou're doing C++, functors or similar are a better idea.

Share this post


Link to post
Share on other sites
I often have a number of predicates for passing the STL algorithms as static functions in my classes. Example:


class Foo {
bool m_alive;

public:
static bool is_alive( const Foo& f ) { return f.m_alive; }
};

...
erase( remove_if( c.begin(), c.end(), Foo::is_valid ), c.end() );



Also useful for sorting and most of the other algorithms. Of course you could just use boost::lambda as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by UziMonkey
Of course you could just use boost::lambda as well.

boost::lambda's a bit of an ogre. For a situation like that, you could get away with std::mem_fun_ref; for more complicated situations, boost::mem_fn would suffice.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by UziMonkey
Of course you could just use boost::lambda as well.

boost::lambda's a bit of an ogre. For a situation like that, you could get away with std::mem_fun_ref; for more complicated situations, boost::mem_fn would suffice.


And let's not forget boost::bind.

Boost::bind augments the capabilities provided by the standard library functions std::bind1st and bind2nd. Typically, the syntax associated with functional composition programming can be quite daunting. Boost::bind functionality is exposed through a normalized syntax making it exceptionally easy to deal with function objects and functions. Its function adapters simplify the code you must write. You need not concern yourself with the usage of adapters such as ptr_fun, mem_fun_ref, and the like. This library adds functionality not achievable through the STL.

And regarding OP's question, I personally think use of static functions is popularized as a result of Object Oriented Programming making functions a big hairy taboo, even in hybrid languages where the functionality is still available (such as C++).

Share this post


Link to post
Share on other sites
I don't know what callbacks are yet. Does that basically mean "do something to object A if some event/condition happens elsewhere"...? That's a stab in the dark.

The posts were a little above my head because I don't know boost:: yet either. Are there cases in programming when you would never create instances of an object?

This leads me to another question about classes. Without creating an instance of a class, I noticed that I can use myClass().memberMethod() to change/use the data. How does it do that without creating a copy of the class (or does it)? Later if you create a new instance:

myClass instanceOfMyClass;

and then access stuff...

instanceOfMyClass.memberMethod();

the method will remain unchanged from how we manipulated it earlier with myClass().memberMethod()

I hope I'm communicating this clear enough.

Share this post


Link to post
Share on other sites
Quote:
Original post by induster
I don't know what callbacks are yet. Does that basically mean "do something to object A if some event/condition happens elsewhere"...? That's a stab in the dark.


"Do something. When you're done, call this callback." When this callback is invoked, you know some/particular action completed.

Quote:
Are there cases in programming when you would never create instances of an object?


Yes. When you don't have any internal state. Calculating cosine of a value, for example. You don't need an object, and there's no context.

Quote:
How does it do that without creating a copy of the class (or does it)? Later if you create a new instance:

myClass instanceOfMyClass;

and then access stuff...

instanceOfMyClass.memberMethod();


First declaration creates an instance. Just not on heap, but on stack. But the constructor gets called, and when you exit the scope (the "}" usually), destructor gets called and memory de-allocated.

Quote:
the method will remain unchanged from how we manipulated it earlier with myClass().memberMethod()


Methods don't change. That particular instance's members may be changed.


void foo()
{
SomeClass c; // c is constructed
c.changeValues(); // values of c are changed
}; // c is destroyed and no longer exists

foo(); // c is created and destroyed on each call to function
foo();
foo();

SomeClass c; // same c is changed 3 times
c.changeValues();
c.changeValues();
c.changeValues();

Share this post


Link to post
Share on other sites
Ah okay. What if we did this:

myClass().setX(5); // set member variable x to 5

and then do this...

myClass().getX(); // return the value of x

obviously the second call will return whatever the x default value is and not 5.

So, by calling a static method without creating an instance of myClass are we able to permanently change data in the class permanently? Or, do we use static on Accessor methods only?

by the way thanks for all the help.

Share this post


Link to post
Share on other sites
Quote:
Original post by induster
So, by calling a static method without creating an instance of myClass are we able to permanently change data in the class permanently? Or, do we use static on Accessor methods only?

Noooooooo. Reread every post above an rethink about it. I think you mix up static methods with normal methods by using the wrong syntax. In all your examples you never called a static method! You ever created an instance and called a non static method belonging to that particular instance.


// non static method call by creating an instance
MyClass().setX(5);

// static method call
MyClass::setX(5);





Quote:
Original post by induster
Ah okay. What if we did this:

myClass().setX(5); // set member variable x to 5

and then do this...

myClass().getX(); // return the value of x

obviously the second call will return whatever the x default value is and not 5.

Antheus wrote an example an said it already! But again.
In your example you are creating 2 instances of the class MyClass with its default constructor MyClass(), then you access each instance with . and call the appropriate method. So the second getX() will never return 5, because it isn't the instance from where you called setX(5).
To access/use the first instance, you will have to use an identifier/a variable name. Create an instance of MyClass like every other variable. ( MyClass myclass_instance; ) Then access the same instance by using its identifier ( myclass_instance.setX(5); myclass_instance.getX(); ).


// create 3 instances which you can only access when
// created, because you don't have an identifier to
// use later
MyClass().set( 1 );
MyClass().set( 2 );
MyClass().set( 3 );

// create ONE instance and call the method ON THIS
// particular instance 3 times
MyClass myclass_instance;
myclass_instance.set( 1 );
myclass_instance.set( 2 );
myclass_instance.set( 3 );







Back to static methods:
Maybe you should write your static method function body and try to access a class member inside it to get the right way of thinking about static methods?

When you use/call a static method then there is no instance of an object. You cant access any of the classes members without an instance. Again, all this was said already in the posts above. But maybe another example will make it more clear to you.

Each non static method of a class gets an additional, invisible (added by the compiler) parameter when called, which determines the right instance to use. Take the following as an example of a static method, which imitates the behaviour of a non static class method.


class MyClass
{

protected:

int value; // our member, which we will set but cannot access from outside the class

public:

// the standard way
void set( int x )
{
// 'this' is a pointer to the current instance
// when the method gets called and is predefined
// by the compiler
this->value = x;
}

// a normal static method
static void setStaticWithoutAnObject( int x )
{
// assign x to what? we have no instance!
// 'this->value = x;' does not work here
// like in the set-method above
}

// a static method which imitates a non static member method
static void setStatic( MyClass* _this, int x )
{
// '_this' is our instance pointer here
if (_this) _this->value = x;
}
};






In this example you can use a static method, but you have to give an appropriate instance when you call it to change the value of the given objects member variable. So the two class methods 'set()' and 'setStatic()' are identical (refering to their behaviour) just with a different name. In both cases you have to give an instance, either 'instance.method()' or 'methodStatic( &instance )'


// create an instance of MyClass
MyClass myclass_instance;

// call method of object and set its value to 5
myclass_instance.set( 5 );

// this static method can do nothing, because there
// is no instance to change something
MyClass::setStaticWithoutAnObject( 5 );

// call a static method and pass a valid instance
// pointer to it to change the instance's value to 5
MyClass::setStatic( &myclass_instance, 5 );







[Edited by - Anntor on March 15, 2008 2:22:06 PM]

Share this post


Link to post
Share on other sites
First, you went through a lot of trouble and I appreciate it. Second, it couldn't be more clear to me now! This was a little hard to wrap my head around at first. Mainly because I didn't understand what happens when using a class that has no instance of itself.

I'm going to work this into my next college assignment somehow, no matter how trivial!

ty ty

Share this post


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

  • Advertisement