[net.lang.c++] Initializing static members

nathan@orstcs.UUCP (nathan) (03/29/86)

Initialization of static members:

I recently discussed C++ with a fine fellow at Mentor Graphics
(who may wish to remain anonymous; I neglected to ask), and
the question came up of how to initialize a static class member.  

With the restriction that no initializer may be provided for the field
(apparently a syntactic hurdle), and that (!) no constructor may
be provided for the class containing it (!), the problem begins to look
interesting.

Question: can a constructor be provided for a derivation of a class
containing a static?  If so, we could do this:

	// in bleah.h
	class bleah {
		static int here;
	public:
		int Here() { return 100; }
	}

	...
	// in bleah.c
	class bleah_hack : bleah {
		bleah_hack() { here = Here(); }
	} b;

Some notes about the example are in order:
	The member function Here() is pretending to be a
	constant field, but it's not even a constant *expression*
	for initializer purposes.  One hopes the optimizer can
	make it as efficient as a true constant.  By the way, 'b'
	above defaults to static, not extern; see r8.1.

If constructors for the derived class are illegal, a friend class
may be needed, kluge-ier yet.

This whole problem, of consts and statics in class declarations,
seems pretty fundamental -- as if the restriction on constructors,
if circumvented this way and not rejected by the compiler, might result
in bad code.  Who understands this issue?

Nathan C. Myers		orstcs!nathan		nathan@oregon-state

weh@druny.UUCP (HopkinsWE) (04/01/86)

In article <34200012@orstcs.UUCP>, nathan@orstcs.UUCP writes:
> Initialization of static members:
> 
> I recently discussed C++ with a fine fellow at Mentor Graphics
> (who may wish to remain anonymous; I neglected to ask), and
> the question came up of how to initialize a static class member.  
> 
> With the restriction that no initializer may be provided for the field
> (apparently a syntactic hurdle),

The "problem" is that no class member may be initialized using the
initialization assignment syntax ( int a = 5; )[NOTE: this same
restriction has always applied to structs, of which classes are
a generalization]: initialization of
member data must be done either within the constructor (which is why
there are constructors), by passing arguments to member data
constructors using the following syntax,
	class1::class1(int arg1,char* arg2): member1(arg1) { ... }

or, if a static member, one can initialize it without reference to
any instance of the class using the class1::static_member syntax.

> and that (!) no constructor may
> be provided for the class containing it (!), the problem begins to look
> interesting.

You've misinterpreted the C++ book. Section 8.5.1 in the reference
manual says , "No initializer can be specified for a static member,
and it cannot be of a class with a constructor." This means that
it cannot be an OBJECT of a class with a constructor, not that it
cannot be a MEMBER of class with a constructor. The reason for this
restriction should be clear: when would the constructor for the static
member be called? The beginning of execution would make sense since
the static member exists whether an instance of the class is constructed
or not, but that may be a bit much to ask of the compiler.

The restriction, "No initializar..." is referring to the use of the
classic initialization syntax for structures,
	struct str1 { static int a, b; } obj = { 1, 2}; // NOT ALLOWED

> 
> Question: can a constructor be provided for a derivation of a class
> containing a static?  If so, we could do this:
> 
> 	// in bleah.h
> 	class bleah {
> 		static int here;
> 	public:
> 		int Here() { return 100; }
> 	}
> 
> 	...
> 	// in bleah.c
> 	class bleah_hack : bleah {
> 		bleah_hack() { here = Here(); }
			       ^^^^^^^^^^^^^ Error
			"here" is private to bleah and cannot be accessed
			by bleah_hack unless "here" is made public or
			bleah declares bleah_hack to be a friend.
> 	} b;
> 
> Some notes about the example are in order:
> 	The member function Here() is pretending to be a
> 	constant field, but it's not even a constant *expression*
> 	for initializer purposes.  One hopes the optimizer can
> 	make it as efficient as a true constant.

Since the definition of the member function Here is included in
the class declaration, it is automatically considered to be an
inline function, in which case it behaves almost like a constant
(there may be an intermediate variable used to contain the
return value).

>	By the way, 'b'
> 	above defaults to static, not extern; see r8.1.

This last remark leads me to believe that you have out of date
documentation. The default scoping has been changed from static
to extern for more compatibility with C. The book in section 8.1
is referring to *storage* class only when it says that the default
is static outside of a function. Unfortunately, I was unable to
find a clear statement in the book about the default scoping
(section 4.1 on scoping only talks of local, file, and class scopes,
not also program scope as was done in an earlier version of the
reference manual).

				Bill Hopkins
				AT&T Information Systems Labs
				11900 N. Pecos St.
				rm 30G11
				Denver, CO 80234
				(303)538-4944
				ihnp4!druny!weh