我正在尝试为私有代码库创建一个公共C ++ API,它也是用C ++编写的。我试着这样做:
这似乎是一种合理的方法。然而,实际上它很快就会导致代码非常笨拙。这是一个代表我遇到的问题的例子。
(编辑:也可以查看代码here)。
namespace Core {
// Base class for all Core classes.
class CoreObject
{
public:
virtual ~CoreObject();
};
class Interface;
class Stream;
class Server : public CoreObject
{
public:
Interface * createInterface();
private:
std::vector<Interface*> mInterfaces;
};
class Interface : public CoreObject
{
public:
void addStream(Stream * stream);
const Stream * getStreamByIndex(std::size_t index) const;
std::size_t streamCount() const;
private:
std::vector<Stream*> mStreams;
};
class Stream : public CoreObject
{
public:
void start();
void stop();
private:
std::string mStats;
};
} // Core
namespace Core {
class CoreObject;
}
namespace API {
class APIStream;
class APIInterface;
// Base class for all API classes.
class APIObject
{
public:
APIObject(Core::CoreObject * inCoreObject);
virtual ~APIObject();
Core::CoreObject * getCoreObject();
const Core::CoreObject * getCoreObject() const;
void setCoreObject(Core::CoreObject * inCoreObject);
private:
Core::CoreObject * mCoreObject;
};
class APIServer : public APIObject
{
public:
APIServer();
APIInterface * createInterface();
};
class APIInterface : public APIObject
{
public:
APIInterface();
void addStream(APIStream * stream);
const APIStream * getStreamByIndex(std::size_t index) const;
APIStream * getStreamByIndex(std::size_t index);
std::size_t streamCount() const;
};
class APIStream : public APIObject
{
public:
APIStream();
void start();
void stop();
};
#include "API.h"
#include "Core.h"
namespace API {
APIObject::APIObject(Core::CoreObject * inCoreObject) :
mCoreObject(inCoreObject)
{
}
APIObject::~APIObject()
{
}
Core::CoreObject * APIObject::getCoreObject()
{
return mCoreObject;
}
const Core::CoreObject * APIObject::getCoreObject() const
{
return mCoreObject;
}
void APIObject::setCoreObject(Core::CoreObject * inCoreObject)
{
mCoreObject = inCoreObject;
}
//
// APIServer
//
APIServer::APIServer() :
APIObject(new Core::Server)
{
}
APIInterface * APIServer::createInterface()
{
Core::Server * coreServer = static_cast<Core::Server*>(getCoreObject());
Core::Interface * coreInterface = coreServer->createInterface();
APIInterface * result(new API::APIInterface);
result->setCoreObject(coreInterface);
return result;
}
//
// APIInterface
//
APIInterface::APIInterface() :
APIObject(new Core::Interface)
{
}
void APIInterface::addStream(APIStream * apiStream)
{
Core::Stream * coreStream = static_cast<Core::Stream *>(apiStream->getCoreObject());
Core::Interface * coreInterface = static_cast<Core::Interface*>(getCoreObject());
coreInterface->addStream(coreStream);
}
//
// APIStream
//
const APIStream * APIInterface::getStreamByIndex(std::size_t index) const
{
const Core::Interface * coreInterface = static_cast<const Core::Interface*>(getCoreObject());
const Core::Stream * coreStream = coreInterface->getStreamByIndex(index);
// Now how I get the the APIStream object?
return 0;
}
std::size_t APIInterface::streamCount() const
{
const Core::Interface * coreInterface = static_cast<const Core::Interface*>(getCoreObject());
return coreInterface->streamCount();
}
APIStream::APIStream() :
APIObject(new Core::Stream)
{
}
void APIStream::start()
{
static_cast<Core::Stream*>(getCoreObject())->start();
}
void APIStream::stop()
{
static_cast<Core::Stream*>(getCoreObject())->stop();
}
} // API
正如您所看到的,实现看起来并不太好。感谢您对这些问题的回答或见解:
我仍然需要在明天的工作中将此解决方案应用于实际代码。我很想知道它在那里有多好。
答案 0 :(得分:4)
当做这种事情时,API和实现对象之间或多或少存在一对一的关系,我通常会使用静态factory method,并且实现类派生自API类。像这样:
class Interface
{
public:
static Interface* Create();
virtual void Foo() = 0;
};
class Concrete : public Interface
{
public:
void Foo() {};
};
Interface* Interface::Create()
{
return new Concrete;
}
这有很多好处。包括:
Create
可以构建许多不同的实现,而Interface
的ABI不必更改。Interface
类型。答案 1 :(得分:2)
请参阅Adapter模式