I would like to split a class implementation into three parts, to avoid that users need to deal with the implementation details, e.g., the libaries that I use to implement the functionality:
impl.cpp
#include <api.h>
#include <impl.h>
Class::Class() {
init();
}
Class::init() {
myData = SomeLibrary::Type(42);
}
Class::doSomething() {
myData.doSomething();
}
impl.h
#include <somelibrary.h>
class Class {
public:
Class();
init();
doSomething();
private:
SomeLibary::Type myData;
}
api.h
class Class {
Class();
doSomething();
}
The problem is, that I am not allowed to redefine headers for the class definition. This does not work when I define Class() and doSomething() only in api.h, either.
A possible option is to define api.h and do not use it in the project at all, but install it (and do not install impl.h).
The obvious drawback is, that I need to make sure, that the common methods in api.h and impl.h always have the same signature, otherwise programs using the library will get linker errors, that I cannot predict when compiling the library.
But would this approach work at all, or will I get other problems (e.g. wrong pointers to class members or similar issues), because the obj file does not match the header?
The short answer is "No!"
The reason: any/all 'client' projects that need to use your Class class have to have the full declaration of that class, in order that the compiler can properly determine such things as offsets for member variables.
The use of private members is fine - client programs won't be able to change them - as is your current implementation, where only the briefest outlines of member functions are provided in the header, with all actual definitions in your (private) source file.
A possible way around this is to declare a pointer to a nested class in Class, where this nested class is simply declared in the shared header: class NestedClass and then you can do what you like with that nested class pointer in your implementation. You would generally make the nested class pointer a private member; also, as its definition is not given in the shared header, any attempt by a 'client' project to access that class (other than as a pointer) will be a compiler error.
Here's a possible code breakdown (maybe not error-free, yet, as it's a quick type-up):
// impl.h
struct MyInternal; // An 'opaque' structure - the definition is For Your Eyes Only
class Class {
public:
Class();
init();
doSomething();
private:
MyInternal* hidden; // CLient never needs to access this! Compiler error if attempted.
}
// impl.cpp
#include <api.h>
#include <impl.h>
struct MyInternal {
SomeLibrary::Type myData;
};
Class::Class() {
init();
}
Class::init() {
hidden = new MyInternal; // MUCH BETTER TO USE unique_ptr, or some other STL.
hidden->myData = SomeLibrary::Type(42);
}
Class::doSomething() {
hidden->myData.doSomething();
}
NOTE: As I hinted in a code comment, it would be better code to use std::unique_ptr<MyInternal> hidden. However, this would require you to give explicit definitions in your Class for the destructor, assignment operator and others (move operator? copy constructor?), as these will need access to the full definition of the MyInternal struct.
The private implementation (PIMPL) idiom can help you out here. It will probably result in 2 header and 2 source files instead of 2 and 1. Have a silly example I haven't actually tried to compile:
api.h
#pragma once
#include <memory>
struct foo_impl;
struct foo {
int do_something(int argument);
private:
std::unique_ptr<foo_impl> impl;
}
api.c
#include "api.h"
#include "impl.h"
int foo::do_something(int a) { return impl->do_something(); }
impl.h
#pragma once
#include <iostream>
struct foo_impl {
foo_impl();
~foo_impl();
int do_something(int);
int initialize_b();
private:
int b;
};
impl.c
#include <iostream>
foo_impl::foo_impl() : b(initialize_b()} { }
foo_impl::~foo_impl() = default;
int foo_impl::do_something(int a) { return a+b++; }
int foo_impl::initialize_b() { ... }
foo_impl can have whatever methods it needs, as foo's header (the API) is all the user will see. All the compiler needs to compile foo is the knowledge that there is a pointer as a data member so it can size foo correctly.
In java there is no header file. We import Class and use function. We can also extend them. In C++ there is header file. We include them and use function. Now my question, how to inherit them like java extends and is it possible?
Every program has its own way of doing something. In c++ you can do like:
//filename foo1.h
class foo1
{
}
Now inn another file say foo2.h
//filename foo2.h
#include "foo1.h"
class foo2 : public foo1
{
}
Java combines two things which C++ separates: the class definition and the definition of its members.
Java:
class Example {
private String s;
protected static int i = 1;
public void f() {
System.out.println("...");
}
public Example() {
s = "test";
}
}
C++ class definition:
class Example
{
private:
std::string s;
protected:
static int i;
public:
void f();
Example();
};
C++ definition of members:
int Example::i = 1;
void Example::f()
{
std::cout << "...\n";
}
Example::Example() :
s("test")
{
}
The separation into *.h and *.cpp files is purely conventional. It typically makes sense to put the class definition into the *.h file and the definition of the members into the *.cpp file. The reason why it makes sense is that some other code using the class only needs the class definition, not the definition of its members. That "other code" includes subclasses. By providing the class definition in a separate file, a user of the class can just #include the header and doesn't need to bother with the *.cpp file.
(Note that the *.cpp file, too, needs to #include its corresponding header file.)
If that looks complicated to you, view it from a different perspective. It allows you to modify the definition of the members without users of your class having to recompile their code. This is a big advantage of C++ compared to Java! The larger your project, the more important an advantage it becomes.
The general way of doing this in c++ with inheritance/polymorphism is by stating the following:
#include "myheaderfile.h"
I'm trying to develop a networking part in my basic game engine in C++, but I'm faced with a rather strange problem (it is for me).
I got a Singleton Networker class that handles the set-up of a socket (UDP) and will try to register the username the client provided to the server, returning a bool that represents if the username is already taken by a different player or not. The class itself does not handle the packets itself, I aim to use a Packethandler class for that.
The problem is that I don't want a client to be able to create a PacketHandler directly because the entire point of the Networker class is to provide some kind of interface for handling that. The first idea I had is 'make the constructor of Packethandler private and create a Singleton' but then ofcourse the client can still ask the instance. Then I quickly though 'well protected then' but Networker is not extending PacketHandler. Then I thought 'well let's make Networker a friend of PacketHandler'. All the info I found up till now seems to discourage Friend usage however, so I wonder:
Is my plan for the simple networking part flawed thus facing me with an issue like this or is my problem the reason friend functionality exists in the first place? What is the take of you guys on this, do you have a much better idea?
Edit: code of my idea.
Packethandler.h
#ifndef FANCY_PACKET_HANDLER
#define FANCY_PACKET_HANDLER
#include <SFML/Network.hpp>
namespace fancy {
namespace network {
class PacketHandler
{
friend class Networker;
private:
sf::IpAddress _hostAddress;
sf::UdpSocket _socket;
PacketHandler(std::string hostAdress);
public:
~PacketHandler();
void sendPacket(const char* packet_data, const unsigned int packet_size);
char* receivePacket();
};
}
}
#endif
Networker.h
#ifndef FANCY_NETWORKER
#define FANCY_NETWORKER
#include <SFML/Network.hpp>
#include <Engine/PacketHandler.h>
namespace fancy {
namespace network {
class Networker
{
public:
static Networker* instance();
bool openUdpSocket(unsigned short port);
bool registerUsername(char* username);
char* receiveOnSocket();
protected:
Networker();
private:
static Networker* _instance;
static PacketHandler* _packetHandler;
const char* _username;
sf::IpAddress _hostAddress;
sf::UdpSocket _socket;
};
}
}
#endif
If you wish to provide an interface and hide all the implementation details, you'd better define a pure virtual class (e.g. Networker) which is visible to a user (say in .h-file), and write an implementation in a descendant class (e.g. NetworkerImpl) which is NOT visible to a user. You can then declare in the header file a function (or even a static method of the Networker class) like Networker *CreateNetworker(); (so the declaration is visible to a user), and then implement the function in .cc file along with your NetworkerImpl (so that the implementation is not visible to a user) like return new NetworkerImpl();.
I have a question regarding hidinging interface details in C++ libraries. The problem is ilustrated with the following example:
Let's say w have a class called ISystem which exposes methods like Init, Run, Tick, Shutdown, GetXXXSubSystem.
Where X are pointers various interfaces like: ISoundSystem, IInputSystem
We also have concrete implementations of ISystem like:
Win32System, OSXSystem etc.
These specific implementations use a pimpl idiom to hide internals
and for example Win32System instantiates Win32RawInputSystem
as input system manager.
All such managers do have their own Init, Run, Tick and Shutdown methods
which are not part of the interface (only concrete implementation) and these are run and managed by the concrete system implementation.
The user calling GetXXXSubSystem gets interface pointer without those methods (Init etc..) but
still he could cast the pointer he gets to concrete implementation
and trigger methods like Init Run Tick etc. which he shouldn't have access to.
The question is, is it possible to hide the concrete class somehow? I tried to make those methods
protected in the concrete implementations and template the class on type which would eventually be friend but this appears to be prohobited and existing hacks do not work with VC11.
The only way I can think of right know is to transfer the concrete implementation declaration from header
into the cpp file of Win32System class but I see ahuge drawback of doing this (even not sure if this would work), because this way each subsystem
would have to be also part of this cpp file and it would become a maintainability nightmare.
Another solution I am thinking about is using factory method like
(RawInput.h)
IInputSystem* CreateRawInputSystem();
(RawInput.cpp)
class RawInput : public IInputSystem {}; ...
and move definition of the class to cpp file but then, how I would acces this type from other parts of my library (ie in Win32System impl)?
Is it possible to include .cpp files form other .cpp files?
Thanks in advance for any tips.
If you're developing a library here, then you can simply choose not to export the header files of the concrete classes that you do not want to expose. You cannot cast to a class of which you do not have a definition.
Example :
MyProjectFolder/Src/Export/ISystem.h
#ifndef ISYSTEM_H
#define ISYSTEM_H
#include "IInputSystem.h"
class ISystem
{
public:
virtual ~ISystem() {};
virtual void Run()=0;
virtual IInputSystem* GetInputSystem()=0;
};
#endif
MyProjectFolder/Src/Export/IInputSystem.h
#ifndef IINPUTSYSTEM_H
#define IINPUTSYSTEM_H
class IInputSystem
{
public:
virtual ~IInputSystem() {};
virtual void Foo()=0;
virtual void Bar()=0;
};
#endif
MyProjectFolder/Src/Export/Win32System.h
#ifndef WIN32SYSTEM_H
#define WIN32SYSTEM_H
#include "ISystem.h"
class Win32System : public ISystem
{
public:
Win32System();
virtual void Run();
virtual IInputSystem* GetInputSystem();
private:
struct impl;
impl* m_pImpl;
};
#endif
MyProjectFolder/Src/Win32RawInputSystem.h
#ifndef WIN32RAWINPUTSYSTEM_H
#define WIN32RAWINPUTSYSTEM_H
#include "IInputSystem.h"
class Win32RawInputSystem : public IInputSystem
{
public:
virtual void Foo();
virtual void Bar();
virtual void Run(); // you do not want to expose that function
};
#endif
MyProjectFolder/Src/Win32System.cpp
#include "Win32System.h"
#include "Win32RawInputSystem.h"
struct Win32System::impl
{
Win32RawInputSystem inputSys;
};
Win32System::Win32System()
: m_pImpl(new impl)
{
}
void Win32System::Run()
{ // run run run
}
IInputSystem* Win32System::GetInputSystem()
{
return &m_pImpl->inputSys;
}
So when building your project its include search path is not only Src/ but also Src/Export/. From within your library project you can use all classes, including Win32RawInputSystem. When deploying your library you only give away those headers that reside in the Src/Export/ folder. Clients can still use the library, but they can never cast IInputSystem* to Win32RawInputSystem* because they do not have that header. Therefore the users of that library can invoke Foo() and Bar() on the IInputSystem*, but they'll never be able to invoke Run().
Anyone knows if is possible to have partial class definition on C++ ?
Something like:
file1.h:
class Test {
public:
int test1();
};
file2.h:
class Test {
public:
int test2();
};
For me it seems quite useful for definining multi-platform classes that have common functions between them that are platform-independent because inheritance is a cost to pay that is non-useful for multi-platform classes.
I mean you will never have two multi-platform specialization instances at runtime, only at compile time. Inheritance could be useful to fulfill your public interface needs but after that it won't add anything useful at runtime, just costs.
Also you will have to use an ugly #ifdef to use the class because you can't make an instance from an abstract class:
class genericTest {
public:
int genericMethod();
};
Then let's say for win32:
class win32Test: public genericTest {
public:
int win32Method();
};
And maybe:
class macTest: public genericTest {
public:
int macMethod();
};
Let's think that both win32Method() and macMethod() calls genericMethod(), and you will have to use the class like this:
#ifdef _WIN32
genericTest *test = new win32Test();
#elif MAC
genericTest *test = new macTest();
#endif
test->genericMethod();
Now thinking a while the inheritance was only useful for giving them both a genericMethod() that is dependent on the platform-specific one, but you have the cost of calling two constructors because of that. Also you have ugly #ifdef scattered around the code.
That's why I was looking for partial classes. I could at compile-time define the specific platform dependent partial end, of course that on this silly example I still need an ugly #ifdef inside genericMethod() but there is another ways to avoid that.
This is not possible in C++, it will give you an error about redefining already-defined classes. If you'd like to share behavior, consider inheritance.
Try inheritance
Specifically
class AllPlatforms {
public:
int common();
};
and then
class PlatformA : public AllPlatforms {
public:
int specific();
};
You can't partially define classes in C++.
Here's a way to get the "polymorphism, where there's only one subclass" effect you're after without overhead and with a bare minimum of #define or code duplication. It's called simulated dynamic binding:
template <typename T>
class genericTest {
public:
void genericMethod() {
// do some generic things
std::cout << "Could be any platform, I don't know" << std::endl;
// base class can call a method in the child with static_cast
(static_cast<T*>(this))->doClassDependentThing();
}
};
#ifdef _WIN32
typedef Win32Test Test;
#elif MAC
typedef MacTest Test;
#endif
Then off in some other headers you'll have:
class Win32Test : public genericTest<Win32Test> {
public:
void win32Method() {
// windows-specific stuff:
std::cout << "I'm in windows" << std::endl;
// we can call a method in the base class
genericMethod();
// more windows-specific stuff...
}
void doClassDependentThing() {
std::cout << "Yep, definitely in windows" << std::endl;
}
};
and
class MacTest : public genericTest<MacTest> {
public:
void macMethod() {
// mac-specific stuff:
std::cout << "I'm in MacOS" << std::endl;
// we can call a method in the base class
genericMethod();
// more mac-specific stuff...
}
void doClassDependentThing() {
std::cout << "Yep, definitely in MacOS" << std::endl;
}
};
This gives you proper polymorphism at compile time. genericTest can non-virtually call doClassDependentThing in a way that gives it the platform version, (almost like a virtual method), and when win32Method calls genericMethod it of course gets the base class version.
This creates no overhead associated with virtual calls - you get the same performance as if you'd typed out two big classes with no shared code. It may create a non-virtual call overhead at con(de)struction, but if the con(de)structor for genericTest is inlined you should be fine, and that overhead is in any case no worse than having a genericInit method that's called by both platforms.
Client code just creates instances of Test, and can call methods on them which are either in genericTest or in the correct version for the platform. To help with type safety in code which doesn't care about the platform and doesn't want to accidentally make use of platform-specific calls, you could additionally do:
#ifdef _WIN32
typedef genericTest<Win32Test> BaseTest;
#elif MAC
typedef genericTest<MacTest> BaseTest;
#endif
You have to be a bit careful using BaseTest, but not much more so than is always the case with base classes in C++. For instance, don't slice it with an ill-judged pass-by-value. And don't instantiate it directly, because if you do and call a method that ends up attempting a "fake virtual" call, you're in trouble. The latter can be enforced by ensuring that all of genericTest's constructors are protected.
or you could try PIMPL
common header file:
class Test
{
public:
...
void common();
...
private:
class TestImpl;
TestImpl* m_customImpl;
};
Then create the cpp files doing the custom implementations that are platform specific.
#include will work as that is preprocessor stuff.
class Foo
{
#include "FooFile_Private.h"
}
////////
FooFile_Private.h:
private:
void DoSg();
How about this:
class WindowsFuncs { public: int f(); int winf(); };
class MacFuncs { public: int f(); int macf(); }
class Funcs
#ifdef Windows
: public WindowsFuncs
#else
: public MacFuncs
#endif
{
public:
Funcs();
int g();
};
Now Funcs is a class known at compile-time, so no overheads are caused by abstract base classes or whatever.
As written, it is not possible, and in some cases it is actually annoying.
There was an official proposal to the ISO, with in mind embedded software, in particular to avoid the RAM ovehead given by both inheritance and pimpl pattern (both approaches require an additional pointer for each object):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0309r0.pdf
Unfortunately the proposal was rejected.
As written, it is not possible.
You may want to look into namespaces. You can add a function to a namespace in another file. The problem with a class is that each .cpp needs to see the full layout of the class.
Nope.
But, you may want to look up a technique called "Policy Classes". Basically, you make micro-classes (that aren't useful on their own) then glue them together at some later point.
Either use inheritance, as Jamie said, or #ifdef to make different parts compile on different platforms.
For me it seems quite useful for definining multi-platform classes that have common functions between them that are platform-independent.
Except developers have been doing this for decades without this 'feature'.
I believe partial was created because Microsoft has had, for decades also, a bad habit of generating code and handing it off to developers to develop and maintain.
Generated code is often a maintenance nightmare. What habits to that entire MFC generated framework when you need to bump your MFC version? Or how do you port all that code in *.designer.cs files when you upgrade Visual Studio?
Most other platforms rely more heavily on generating configuration files instead that the user/developer can modify. Those, having a more limited vocabulary and not prone to be mixed with unrelated code. The configuration files can even be inserted in the binary as a resource file if deemed necessary.
I have never seen 'partial' used in a place where inheritance or a configuration resource file wouldn't have done a better job.
Since headers are just textually inserted, one of them could omit the "class Test {" and "}" and be #included in the middle of the other.
I've actually seen this in production code, albeit Delphi not C++. It particularly annoyed me because it broke the IDE's code navigation features.
Dirty but practical way is using #include preprocessor:
Test.h:
#ifndef TEST_H
#define TEST_H
class Test
{
public:
Test(void);
virtual ~Test(void);
#include "Test_Partial_Win32.h"
#include "Test_Partial_OSX.h"
};
#endif // !TEST_H
Test_Partial_OSX.h:
// This file should be included in Test.h only.
#ifdef MAC
public:
int macMethod();
#endif // MAC
Test_Partial_WIN32.h:
// This file should be included in Test.h only.
#ifdef _WIN32
public:
int win32Method();
#endif // _WIN32
Test.cpp:
// Implement common member function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
Test::Test(void)
{
}
Test::~Test(void)
{
}
Test_Partial_OSX.cpp:
// Implement OSX platform specific function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
#ifdef MAC
int Test::macMethod()
{
return 0;
}
#endif // MAC
Test_Partial_WIN32.cpp:
// Implement WIN32 platform specific function of class Test in this file.
#include "stdafx.h"
#include "Test.h"
#ifdef _WIN32
int Test::win32Method()
{
return 0;
}
#endif // _WIN32
Suppose that I have:
MyClass_Part1.hpp, MyClass_Part2.hpp and MyClass_Part3.hpp
Theoretically someone can develop a GUI tool that reads all these hpp files above and creates the following hpp file:
MyClass.hpp
class MyClass
{
#include <MyClass_Part1.hpp>
#include <MyClass_Part2.hpp>
#include <MyClass_Part3.hpp>
};
The user can theoretically tell the GUI tool where is each input hpp file and where to create the output hpp file.
Of course that the developer can theoretically program the GUI tool to work with any varying number of hpp files (not necessarily 3 only) whose prefix can be any arbitrary string (not necessarily "MyClass" only).
Just don't forget to #include <MyClass.hpp> to use the class "MyClass" in your projects.
Declaring a class body twice will likely generate a type redefinition error. If you're looking for a work around. I'd suggest #ifdef'ing, or using an Abstract Base Class to hide platform specific details.
You can get something like partial classes using template specialization and partial specialization. Before you invest too much time, check your compiler's support for these. Older compilers like MSC++ 6.0 didn't support partial specialization.
This is not possible in C++, it will give you an error about redefining already-defined
classes. If you'd like to share behavior, consider inheritance.
I do agree on this. Partial classes is strange construct that makes it very difficult to maintain afterwards. It is difficult to locate on which partial class each member is declared and redefinition or even reimplementation of features are hard to avoid.
Do you want to extend the std::vector, you have to inherit from it. This is because of several reasons. First of all you change the responsibility of the class and (properly?) its class invariants. Secondly, from a security point of view this should be avoided.
Consider a class that handles user authentication...
partial class UserAuthentication {
private string user;
private string password;
public bool signon(string usr, string pwd);
}
partial class UserAuthentication {
private string getPassword() { return password; }
}
A lot of other reasons could be mentioned...
Let platform independent and platform dependent classes/functions be each-others friend classes/functions. :)
And their separate name identifiers permit finer control over instantiation, so coupling is looser. Partial breaks encapsulation foundation of OO far too absolutely, whereas the requisite friend declarations barely relax it just enough to facilitate multi-paradigm Separation of Concerns like Platform Specific aspects from Domain-Specific platform independent ones.
I've been doing something similar in my rendering engine. I have a templated IResource interface class from which a variety of resources inherit (stripped down for brevity):
template <typename TResource, typename TParams, typename TKey>
class IResource
{
public:
virtual TKey GetKey() const = 0;
protected:
static shared_ptr<TResource> Create(const TParams& params)
{
return ResourceManager::GetInstance().Load(params);
}
virtual Status Initialize(const TParams& params, const TKey key, shared_ptr<Viewer> pViewer) = 0;
};
The Create static function calls back to a templated ResourceManager class that is responsible for loading, unloading, and storing instances of the type of resource it manages with unique keys, ensuring duplicate calls are simply retrieved from the store, rather than reloaded as separate resources.
template <typename TResource, typename TParams, typename TKey>
class TResourceManager
{
sptr<TResource> Load(const TParams& params) { ... }
};
Concrete resource classes inherit from IResource utilizing the CRTP. ResourceManagers specialized to each resource type are declared as friends to those classes, so that the ResourceManager's Load function can call the concrete resource's Initialize function. One such resource is a texture class, which further uses a pImpl idiom to hide its privates:
class Texture2D : public IResource<Texture2D , Params::Texture2D , Key::Texture2D >
{
typedef TResourceManager<Texture2D , Params::Texture2D , Key::Texture2D > ResourceManager;
friend class ResourceManager;
public:
virtual Key::Texture2D GetKey() const override final;
void GetWidth() const;
private:
virtual Status Initialize(const Params::Texture2D & params, const Key::Texture2D key, shared_ptr<Texture2D > pTexture) override final;
struct Impl;
unique_ptr<Impl> m;
};
Much of the implementation of our texture class is platform-independent (such as the GetWidth function if it just returns an int stored in the Impl). However, depending on what graphics API we're targeting (e.g. Direct3D11 vs. OpenGL 4.3), some of the implementation details may differ. One solution could be to inherit from IResource an intermediary Texture2D class that defines the extended public interface for all textures, and then inherit a D3DTexture2D and OGLTexture2D class from that. The first problem with this solution is that it requires users of your API to be constantly mindful of which graphics API they're targeting (they could call Create on both child classes). This could be resolved by restricting the Create to the intermediary Texture2D class, which uses maybe a #ifdef switch to create either a D3D or an OGL child object. But then there is still the second problem with this solution, which is that the platform-independent code would be duplicated across both children, causing extra maintenance efforts. You could attempt to solve this problem by moving the platform-independent code into the intermediary class, but what happens if some of the member data is used by both platform-specific and platform-independent code? The D3D/OGL children won't be able to access those data members in the intermediary's Impl, so you'd have to move them out of the Impl and into the header, along with any dependencies they carry, exposing anyone who includes your header to all that crap they don't need to know about.
API's should be easy to use right and hard to use wrong. Part of being easy to use right is restricting the user's exposure to only the parts of the API they should be using. This solution opens it up to be easily used wrong and adds maintenance overhead. Users should only have to care about the graphics API they're targeting in one spot, not everywhere they use your API, and they shouldn't be exposed to your internal dependencies. This situation screams for partial classes, but they are not available in C++. So instead, you might simply define the Impl structure in separate header files, one for D3D, and one for OGL, and put an #ifdef switch at the top of the Texture2D.cpp file, and define the rest of the public interface universally. This way, the public interface has access to the private data it needs, the only duplicate code is data member declarations (construction can still be done in the Texture2D constructor that creates the Impl), your private dependencies stay private, and users don't have to care about anything except using the limited set of calls in the exposed API surface:
// D3DTexture2DImpl.h
#include "Texture2D.h"
struct Texture2D::Impl
{
/* insert D3D-specific stuff here */
};
// OGLTexture2DImpl.h
#include "Texture2D.h"
struct Texture2D::Impl
{
/* insert OGL-specific stuff here */
};
// Texture2D.cpp
#include "Texture2D.h"
#ifdef USING_D3D
#include "D3DTexture2DImpl.h"
#else
#include "OGLTexture2DImpl.h"
#endif
Key::Texture2D Texture2D::GetKey() const
{
return m->key;
}
// etc...