From: Stefan S. <ste...@or...> - 2003-01-31 16:12:51
|
hi there, Murray asked me to drag some points we were discussing on the patch manager into this list... We were discussing some code styling issues, and I'd like to raise these points again here: 1) I suggest to use 'using namespace xmlpp;' inside .cc files, as that is more restrictive. It means that the compiler will not put any additional symbols *declared* in the .cc file into the xmlpp namespace, but only associate *definitions* with declarations from the headers. I prefer that because it's more explicit. (Specifically, when you explicitely want to hide symbols, put them into anonymous namespaces) 2) 'using foomethod;' in derived class declaration: Murray suggests people may not be familiar with that concept. The goal of this shortcut is to drag base class methods into the derived class. A more lengthy way would be to write 'foomethod() { BaseClass::foomethod();} That's relevant in two situations: a) the base method declares the method in question as being protected, while the derived class wants to expose it publicly. b) the derived class overrides the method by a method with the same name, but a different signature. Example: the base class has 'void foo();', and the derived class defines 'void foo(int);'. This would hide the original 'void foo();' method, so if you want to expose both, you have to redeclare (via 'using') or redefine it. 3) hiding state in the private section: It's a matter of good encapsulation to put all members into the private section, and then provide accessors (either public or protected). That helps to decouple dependencies between base and derived classes. Of course, derived classes then can't access the member variable. That's exactly the point, that's the goal ! Comments and criticism are appreciated... Stefan |
From: <mu...@t-...> - 2003-01-31 16:42:36
|
On Fri, 2003-01-31 at 17:13, Stefan Seefeld wrote: > 3) hiding state in the private section: > It's a matter of good encapsulation to put all members into the > private section, and then provide accessors (either public or > protected). That helps to decouple dependencies between base and > derived classes. Of course, derived classes then can't access the > member variable. That's exactly the point, that's the goal ! And I say "you can't predict the future" so you should not completely hide complex types. For instance, in gtkmm, every class has a gobj() accessor so people can get at the underlying C instance if we haven't wrapped something. This will be the same in libxml++ - if people need to use a libxml function that isn't wrapped in libxml++ then they will need access to the pointer to the underlying C struct. I intend to add cobj() accessors if we apply your patch. |
From: Jonathan W. <co...@co...> - 2003-02-01 18:20:05
|
On Fri, Jan 31, 2003 at 11:13:34AM -0500, Stefan Seefeld wrote: > 1) I suggest to use 'using namespace xmlpp;' inside .cc files, IMHO this is a Good Thing. > 2) 'using foomethod;' in derived class declaration: > Murray suggests people may not be familiar with that concept. > The goal of this shortcut is to drag base class methods into the > derived class. A more lengthy way would be to write > 'foomethod() { BaseClass::foomethod();} > > That's relevant in two situations: > a) the base method declares the method in question as being > protected, while the derived class wants to expose it publicly. > b) the derived class overrides the method by a method with the same > name, but a different signature. Example: (N.B. this is an overload, not an override) > the base class has 'void foo();', and the derived class defines > 'void foo(int);'. This would hide the original 'void foo();' > method, so if you want to expose both, you have to redeclare (via > 'using') or redefine it. FYI: GCC 2.95 doesn't support using declarations at class scope if the name is subsequently overloaded, so hidden functions must be redefined. RedHat's GCC 2.96 does support such using decls, but FreeBSD's 2.95.4 doesn't, and AFAIK Debian's 2.95.4 doesn't either. Should libxml++ work with GCC 2.95 ? jon -- "Always Read the Label" - anon. |
From: Christophe de V. <cde...@al...> - 2003-02-01 18:32:10
|
Le Samedi 1 F=E9vrier 2003 19:15, Jonathan Wakely a =E9crit : > Should libxml++ work with GCC 2.95 ? Since it's still probably more widely used than gcc 3.x, yes. Christophe |
From: Stefan S. <se...@sy...> - 2003-02-01 21:20:49
|
Jonathan Wakely wrote: > GCC 2.95 doesn't support using declarations at class scope if the name > is subsequently overloaded, so hidden functions must be redefined. > RedHat's GCC 2.96 does support such using decls, but FreeBSD's 2.95.4 > doesn't, and AFAIK Debian's 2.95.4 doesn't either. > Should libxml++ work with GCC 2.95 ? I'm puzzled, I just tried to compile this chunk with a home-built 2.95.3: ---- class A { protected: void foobar(); }; class B : public A { public: using A::foobar; }; ---- with 'gcc version 2.95.3 20010315 (release)' and it worked fine. Stefan |
From: Jonathan W. <co...@co...> - 2003-02-02 16:27:51
|
On Sat, Feb 01, 2003 at 05:19:00PM -0500, Stefan Seefeld wrote: > >GCC 2.95 doesn't support using declarations at class scope if the name > >is subsequently overloaded, so hidden functions must be redefined. ^^^^^^^^^^^^^^^^^^^^^^^ > >RedHat's GCC 2.96 does support such using decls, but FreeBSD's 2.95.4 > >doesn't, and AFAIK Debian's 2.95.4 doesn't either. > >Should libxml++ work with GCC 2.95 ? > > I'm puzzled, I just tried to compile this chunk with a home-built 2.95.3: > > ---- > class A > { > protected: > void foobar(); > }; > > class B : public A > { > public: > using A::foobar; void foobar(int); // overload, hides A::foobar > }; > ---- > > with 'gcc version 2.95.3 20010315 (release)' > > and it worked fine. Yes, this is case (a) in the original mail, where a using decl changes the access to a name. GCC 2.95 supports this. It doesn't support case (b), where a using decl prevents name hiding. If you make the change above (overload foobar in the derived class, which would hide A::foobar if the using decl weren't present) and GCC 2.95 should fail with this error: hiding3.cc:12: cannot adjust access to `void A::foobar()' in `class B' hiding3.cc:11: because of local method `void B::foobar(int)' with same name Even the error message implies that in GCC 2.95 the only purpose of a using decl is to change access, as in case (a), whereas the C++ standard intends using decls to also prevent name-hiding, case (b). If you now try to call A::foobar through an object of type B, like so: int main() { B b; b.foobar(); } then you should get this error: hiding3.cc: In function `int main()': hiding3.cc:17: no matching function for call to `B::foobar ()' hiding3.cc:11: candidates are: void B::foobar(int) Therefore to prevent name-hiding you must modify B like so: class B : public A { public: void foobar() { A::foobar(); } // redefine, using A's implementation void foobar(int); }; This only applies to case (b), where the name is overloaded in the derived class. This fails for me with GCC 2.95.2, FreeBSD's (unofficial) 2.95.4 and Debian's (unofficial) 2.95.4, but works with RedHat's 2.96. I can't check that it fails for the official 2.95.3, but I would be surprised if it doesn't. jon -- "A scientific theory should be as simple as possible, but no simpler." - Albert Einstein |
From: Stefan S. <se...@sy...> - 2003-02-02 19:31:50
|
hi Jonathan, thanks for the clarification ! Fortunately the way I use the 'using' directive in my patch is as in (a), i.e. to lift an existing method from the 'protected' into the 'public' part, so we should be fine. Regards, Stefan |