gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) (05/10/91)
Can anyone tell me why it is not possible to statically
initialize an instance of a class containing virtual functions?
Both Zortech C++ and Borland C++ give an error at the
'{1,2,3}' in the following example:
class TESTCLASS
{
public:
int a,b,c;
virtual void testfunc();
};
void TESTCLASS::testfunc() {}
TESTCLASS test = {1,2,3};
I realize that there will be a 'hidden' instance variable, being
a pointer to the virtual function table, but I can't quite grasp
why the compiler can't generate it. (The example works fine when
testfunc() is not virtual).
steve@taumet.com (Stephen Clamage) (05/12/91)
gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) writes: >Both Zortech C++ and Borland C++ give an error at the >'{1,2,3}' in the following example: >class TESTCLASS > { > public: > int a,b,c; > virtual void testfunc(); > }; >void TESTCLASS::testfunc() {} >TESTCLASS test = {1,2,3}; The C++ rule is that a class may be statically intialized using C-style initialization syntax as long as it doesn't have "class-like" features. Class-like features require a constructor to be called, which is not supported by the C syntax. You can look up in the ARM to find the full details of what is allowed. The easiest way to remember it is that a class can be initialized with C syntax if it looks like a C struct. Otherwise, use a constructor. (This is overly restrictive, but will keep you out of trouble.) In your specific instance, a class with virtual functions requires a (pointer to the) table of the virtual functions to be part of the class, something done by the constructor. The '={1,2,3}' syntax precludes calling a contructor, and hence is illegal. -- Steve Clamage, TauMetric Corp, steve@taumet.com
jimad@microsoft.UUCP (Jim ADCOCK) (05/15/91)
In article <1991May10.063358.15955@ccu1.aukuni.ac.nz> gkean@ccu1.aukuni.ac.nz (Graham Kean;;g_kean) writes: |Can anyone tell me why it is not possible to statically |initialize an instance of a class containing virtual functions? | |class TESTCLASS | { | public: | int a,b,c; | virtual void testfunc(); | }; |void TESTCLASS::testfunc() {} |TESTCLASS test = {1,2,3}; The problem is not that you are trying to statically initialize an instance of a class containing virtual functions, but rather that you are trying to initialize a class with virtual functions with an initializer list. ARM 8.4.1 states that you are only allowed to use initializer lists with objects of classes with no constructors, no private nor protected members, no bases classes, nor any virtual functions. I don't see where there would be any great difficulty for most compilers to statically initialize your vtable pointer, its just that the standard tells them not to do so. I'd guess the rationale is that if you want to be using inheritence and polymophism, you really "ought" to be be doing it the C++ way, using constructors to get your object to a safe default state, and then use member functions to modify that state. Alternatively, for C backwards compatibility with C-like structures, C++ still supports initializer lists. Compilers could be required to support strategies that fall in between, but I guess it wasn't considered worthwhile. With the present rules, compiler writers are assured that all vtable ptr initializations can happen within compiler generated constructors. Your desired feature would require them to be a little bit smarter.