Article View: comp.std.c++
Article #218Declarations of Member Functions Outside Class Definitions
From: Scott Meyers
Date: Wed, 01 Aug 1990 20:05
Date: Wed, 01 Aug 1990 20:05
144 lines
4636 bytes
4636 bytes
Proposed:
That it be possible to declare member functions outside of class
declarations exclusively for the purpose of later friend declarations.
Example:
class Example; // currently legal
void Example::f(int); // currently illegal, but would be ok
class Sample {
friend void Example::f(int); // currently legal, provided class
// Example has been defined
function()
{
void (Example::*pmf)(int) =
Example::f; // currently illegal and would
// remain illegal
}
};
Motivation:
Such a change would make it easier to declare certain friend
relationships without having to embed #include directives in the middle
of header files.
As an example, consider the following classes:
- WithFriend, which has a private int member and which declares the
constructor for class Derived as a friend.
- Base, which has a constructor that takes an int as an argument.
- Derived, a derived class of Base, that has a constructor that takes a
WithFriend reference as an argument and initializes the Base
constructor with the private int member of the referenced WithFriend.
This must currently be declared as follows:
class Base {
protected:
Base(int baseArg) {}
};
class WithFriend;
class Derived: public Base {
public:
Derived(WithFriend& derivedArg);
};
class WithFriend {
friend Derived::Derived(WithFriend&);
private:
int privateMember;
};
inline Derived::Derived(WithFriend& derivedArg)
: Base(derivedArg.privateMember) {}
With the proposed change, it could be declared as follows:
class WithFriend;
extern Derived::Derived(WithFriend&); // currently illegal
class WithFriend {
friend Derived::Derived(WithFriend&);
private:
int privateMember;
};
class Base {
protected:
Base(int baseArg) {}
};
class Derived: public Base {
public:
Derived(WithFriend& derivedArg)
: Base(derivedArg.privateMember) {}
};
The latter declaration is a little cleaner, in my opinion, because all
the forward declarations are at the beginning and there is no need to
separate the inline body of the Derived constructor from the class
declaration, but that's hardly compelling. The important situation --
and the common one -- is when WithFriend is declared in a different file
from Base and Derived, say WithFriend.h and Base.h, respectively. Then
the declaration must be as follows:
class Base {
protected:
Base(int baseArg) {}
};
class WithFriend;
class Derived: public Base {
public:
Derived(WithFriend& derivedArg);
};
#include "WithFriend.h"
inline Derived::Derived(WithFriend& derivedArg)
: Base(derivedArg.privateMember) {}
In this case the #include directive must occur in the middle of the file,
contrary to intuition and common convention for #include file usage.
With the proposed change, the #include directives need only occur at the
top of files:
class WithFriend; // file WithFriend.h
extern Derived::Derived(WithFriend&);
class WithFriend {
friend Derived::Derived(WithFriend&);
private:
int privateMember;
};
-------------------------------------------------------------------------
#include "WithFriend.h" // file Base.h
class Base {
protected:
Base(int baseArg) {}
};
class Derived: public Base {
public:
Derived(WithFriend& derivedArg)
: Base(derivedArg.privateMember) {}
};
Note that allowing member functions to be declared but not used is
similar to the standard C++ facility for allowing class names to be
declared but no objects of those classes to be used prior to class
definition.
Scott
sdm@cs.brown.edu
Technical Details
Message-ID:
<46393@brunix.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!mailrus!umich!samsung!sdd.hp.com!decwrl!uunet!brunix!sdmShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!mailrus!umich!samsung!sdd.hp.com!decwrl!uunet!brunix!sdm From: sdm@cs.brown.edu (Scott Meyers) Newsgroups: comp.std.c++ Subject: Declarations of Member Functions Outside Class Definitions Message-ID: <46393@brunix.UUCP> Date: 1 Aug 90 20:05:31 GMT Sender: news@brunix.UUCP Reply-To: sdm@cs.brown.edu (Scott Meyers) Organization: Brown University Department of Computer Science Lines: 144