why a member function in this example must be static?
Hi
This is a code example from chapter 12 of Bruce Eckel's Thinking in C++ vol1.
I cant figure out why the member function make() must be declared as static. This does not conform with regular use of static function I'm familiar with (use it with static member data). This class doesnt have any static member data.
When I remove static, I got a compile error.
http://www.mindview.net/ has the complete code example.
Can u help? : )
class Dog {
string nm;
int refcount;
Dog(const string& name)
: nm(name), refcount(1) {
cout << "Creating Dog: " << *this << endl;
}
// Prevent assignment:
Dog& operator=(const Dog& rv);
public:
// Dogs can only be created on the heap:
static Dog* make(const string& name) {
return new Dog(name);
}
Dog(const Dog& d)
: nm(d.nm + " copy"), refcount(1) {
cout << "Dog copy-constructor: "
<< *this << endl;
}
~Dog() {
cout << "Deleting Dog: " << *this << endl;
}
void attach() {
++refcount;
cout << "Attached Dog: " << *this << endl;
}
void detach() {
require(refcount != 0);
cout << "Detaching Dog: " << *this << endl;
// Destroy object if no one is using it:
if(--refcount == 0) delete this;
}
// Conditionally copy this Dog.
// Call before modifying the Dog, assign
// resulting pointer to your Dog*.
Dog* unalias() {
cout << "Unaliasing Dog: " << *this << endl;
// Don't duplicate if not aliased:
if(refcount == 1) return this;
--refcount;
// Use copy-constructor to duplicate:
return new Dog(*this);
}
void rename(const string& newName) {
nm = newName;
cout << "Dog renamed to: " << *this << endl;
}
friend ostream&
operator<<(ostream& os, const Dog& d) {
return os << "[" << d.nm << "], rc = "
<< d.refcount;
}
};
1 Attachment(s)
Re: why a member function in this example must be static?
Hi
Sorry I didnt format the code properly in the previous post.
This is a code example from chapter 12 of Bruce Eckel's Thinking in C++ vol1.
I cant figure out why the member function make() must be declared as static. This does not conform with regular use of static function I'm familiar with (use it with static member data). This class doesnt have any static member data.
When I remove static, I got a compile error.
http://www.mindview.net/ has the complete code example.
Can u help? : )
Thanks
Ken
Code:
class Dog {
string nm;
int refcount;
Dog(const string& name)
: nm(name), refcount(1) {
cout << "Creating Dog: " << *this << endl;
}
// Prevent assignment:
Dog& operator=(const Dog& rv);
public:
// Dogs can only be created on the heap:
static Dog* make(const string& name) {
return new Dog(name);
}
Dog(const Dog& d)
: nm(d.nm + " copy"), refcount(1) {
cout << "Dog copy-constructor: "
<< *this << endl;
}
~Dog() {
cout << "Deleting Dog: " << *this << endl;
}
void attach() {
++refcount;
cout << "Attached Dog: " << *this << endl;
}
void detach() {
require(refcount != 0);
cout << "Detaching Dog: " << *this << endl;
// Destroy object if no one is using it:
if(--refcount == 0) delete this;
}
// Conditionally copy this Dog.
// Call before modifying the Dog, assign
// resulting pointer to your Dog*.
Dog* unalias() {
cout << "Unaliasing Dog: " << *this << endl;
// Don't duplicate if not aliased:
if(refcount == 1) return this;
--refcount;
// Use copy-constructor to duplicate:
return new Dog(*this);
}
void rename(const string& newName) {
nm = newName;
cout << "Dog renamed to: " << *this << endl;
}
friend ostream&
operator<<(ostream& os, const Dog& d) {
return os << "[" << d.nm << "], rc = "
<< d.refcount;
}
};
Re: why a member function in this example must be static?
In this case, the constructor is private, so there's no way for you to make a 'dog' in code.
There must be a 'make' function to do that in this case. This example is trivial, so it's not clear why the 'dog' can only be created by a function - but in this case the author intends to make certain the only way for a dog to exist is to be created from the heap.
The make function takes control of the creation to ensure that. Why you want to ensure this for dog is unclear, but there are situations (you'll know when this comes up) where you need to control the creation of an object.
Now, since the constructor is private, you must have a function that has permission to access the private constructor. That must be a member function - anything not a member wouldn't gain permission unless it were made a friend, and you can't make 'global scope' a friend - that would basically move all private members into the public.
So, a member function (public) is required to 'make' a dog in a controlled manner. The paradox is that you can't call a 'standard' or 'non-static' member function unless you have a dog object, and since you can't make a dog object on your own, you're stuck.
Static functions don't require an object for their call - they don't have a 'this' pointer, but as members, gain access to the internals - the private constructor in this case.
This is the only way you can make a dog, with it's private constructor, without first having a dog.
Re: why a member function in this example must be static?
Thanks JVene
I now have better understanding of static member function. Their use is not only to change static member data, but also can manipulate a class even when there is yet object created.
: )
Ken
Re: why a member function in this example must be static?
a static "member" is simply a global "member" and not a a class member.
Re: why a member function in this example must be static?
Quote:
Originally Posted by Mitsukai
a static "member" is simply a global "member" and not a a class member.
That's a very simplistic and misleading way of putting it.
A static member function differs from a "normal" member function in that it has no implied "this" argument, so does not require an object of that class in order to call it. It most certainly is a class member, since it retains all the access rights of a non-static member. So, if you supply an object to the function, or if it creates one for itself, it can "see" all the protected and provate members of that class. This is why static functions are useful as factory functions for ensuring that objects are created on the free store.
Re: why a member function in this example must be static?
Re: why a member function in this example must be static?
You can do a search on "Design Patterns". This looks like the Factory design pattern, in which some subset of code instantiates the proper class object.
In this case, it always instantiates Dog in the make() method. This is ideal in situations where the code, not the user, must best decide which class to instantiate. Should it create Dog, or perhaps subclasses like GreatDane, Rottweiler, or Mutt?