我想开始在我的C ++代码中添加一些接口,以便我更容易使用模拟进行单元测试。
这个问题是从C ++中的方法返回抽象类是一件痛苦的事。您不能按值返回,因此您需要返回指针或引用。
考虑到过去六七年中C ++的所有发展,我想我会问是否有更好的方法来返回抽象基类。没有噪音的接口看起来像这样,但我确信这是不可能的。
IBaseInterface getThing() {return DerivedThing{};}
我记得过去这样做的方法是使用指针(现在可能是智能指针):
std::unique_ptr<IBaseInterface> getThing() {return std::make_unique<DerivedThing>();}
指针的问题在于我实际上从未计划利用nullptr,因此处理指针而不是值的开销和噪音不会让我失去作为读者的价值。
我有更好的方法来处理这个问题吗?
答案 0 :(得分:4)
编辑:提供完整的示例,包括使多态处理可复制。
#include <iostream>
#include <utility>
#include <memory>
struct IBaseInterface {
IBaseInterface() = default;
IBaseInterface(IBaseInterface const&) = default;
IBaseInterface(IBaseInterface &&) = default;
IBaseInterface& operator=(IBaseInterface const&) = default;
IBaseInterface& operator=(IBaseInterface &&) = default;
virtual ~IBaseInterface() = default;
virtual std::unique_ptr<IBaseInterface> clone() const = 0;
virtual void do_thing() = 0;
};
struct handle
{
handle(std::unique_ptr<IBaseInterface> ptr)
: _impl(std::move(ptr))
{}
handle(handle const& r)
: _impl(r._impl->clone())
{}
handle(handle && r)
: _impl(std::move(r._impl))
{}
handle& operator=(handle const& r)
{
auto tmp = r;
std::swap(_impl, tmp._impl);
return *this;
}
handle& operator=(handle && r)
{
_impl = std::move(r._impl);
return *this;
}
// interface here
void do_thing() { _impl->do_thing(); }
private:
std::unique_ptr<IBaseInterface> _impl;
};
struct DerivedThing : IBaseInterface
{
std::unique_ptr<IBaseInterface> clone() const override
{
return std::make_unique<DerivedThing>(*this);
}
void do_thing() override
{
std::cout << "I'm doing something" << std::endl;
}
};
handle make_thing()
{
return handle(std::make_unique<DerivedThing>());
};
int main()
{
auto a = make_thing();
auto b = a;
a.do_thing();
b.do_thing();
return 0;
}
现在使用你的句柄,好像它有(可移动的)值语义