问题
What's the recommendation regarding conditionally defining member functions in a C++ class? (The question is centered around limiting the external exposure of some classes in a DLL - specifically when those classes are passed in as a parameter). Obviously this isn't something you want to do to data members, but functions should be OK shouldn't they?
For example:
class A
{
public:
void func1();
#ifdef _CONDITION_
void func2(B b);
#endif
};
Edited: Added public modifier to avoid example confusion.
回答1:
Generally if you wont want to expose parts of an exported class, then you should consider the option of not exposing the class, but instead providing an abstract interface that your class inherits from.
eg.
class AbstractExportedInterface
{
public:
virtual void do_stuff() = 0;
};
class HasStuffIDontWantToExport : public AbstractExportedInterface
{
public:
void do_stuff();
void do_other_stuff_that_i_dont_export();
};
then you would operate on the assumption that you are providing a HasStuffIDontWantToExport* to the DLL user and they only have headers for AbstractExportedInterface.
EDIT: Response to first comment
If you have some types (3rd party or otherwise) that you want your client of the DLL to be able to use in some way, but you dont want them to have full access to those types, and you dont have the flexibility to use a direct inheritance hierarchy to create an abstract interface. You might be able to use pimpl pattern to create proxy interfaces for each of the types you want your client to have limited usage of?
eg.
class ExportedAbstractProxyObject
{
public:
virtual void do_stuff() = 0;
};
#include <3rdPartyType.h>
class ProxyObject
{
public:
void do_stuff() { pimpl_.actually_do_stuff(); }
private:
3rdPartyType pimpl_;
};
class ExportedAbstractProxyOtherObject
{
public:
virtual void do_stuff_with_thing(ExportedAbstractProxyObject* thing) = 0;
};
class ProxyOtherObject
{
public:
void do_stuff_with_thing(ExportedAbstractProxyObject* thing) { thing->do_stuff(); }
};
So then you can happily export whatever interfaces you like, and completely hide the implementation and 3rd party types inside your DLL. The downside is you obviously then have to create all those proxy object interfaces.
回答2:
Not entirely sure what you're asking, but if the member functions are intended to be private to the class use the 'private:' keyword to make them private.
If instead they're intended to be used by other classes within the context of the module where the class lives, but you don't want external entities knowing about them, make them public but derive the class from an 'interface' base class, and expose that interface base class to external entities.
回答3:
That sort of thing is generally done using public
/protected
/private
declarations, and possibly friend
s, rather than preprocessor conditions. But in one program I've written where it was more of a problem to declare a certain set of functions as private or protected (because of the number of stand-alone functions that needed access to them), I prefixed the pseudo-private function names with an underscore (along with clear comments explaining why), to make it clear to the reader that those functions weren't meant for general use.
回答4:
You say you want to prevent visibility of some of the classes, but your example only hides a single method.
If a class doesn't form part of the "public" interface of your DLL you don't need to publish the header. For example:
// foo.h
class Bar;
class Foo
{
private Bar* _bar;
...
}
Here "Bar" is part of the implementation so there is no need to ship its header. If Bar is used only by Foo, you could also define it within the private/protected scope in Foo.
来源:https://stackoverflow.com/questions/5684071/conditional-member-functions