类似Pimpl的封装导向使用模式

时间:2013-09-08 06:40:32

标签: c++ c++11 constructor rvalue-reference

我只想让我的实现依赖于另一个头。

HDR:

// FDS.h

#include "MyMath.h"

union FancyDataStructure() {
    FancyDataStructure(): state(MyIdentityMat4), fanciful(0.31337) {}
    struct { MyMat4 state; float fanciful; };
    struct { 
        MyVec4 c0;
        MyVec4 c1;
        MyVec4 c2;
        MyVec4 c3;
        float fancy;
    };
}

// please pretend this has a good reason for existing
struct MyMat48() {
    MyMat48() {}
    MyMat48(const MyMat4& l, const MyMat4& r): left(l), right(r) {}
    FancyDataStructure left;
    FancyDataStructure right;
};

IMPL:

// FDS.cpp

#include "FDS.h"
#include "include/FlakyLib.hpp"

void init(MyMat48& instance, const FlakyLibrary::mat4& with) {
    instance.left.c2 = MyVec4(
                           with.FlakyMat4Subscript(3),
                           with.FlakyMat4Subscript(1), 
                           with.FlakyMat4Subscript(0), 
                           with.FlakyMat4Subscript(2), 
                       );
    instance.right.fancy = with.FlakyMat4Determinant();
    // This performs a crazy swizzle which demonstrates use of FlakyLib methods
}

extern std::vector<MyMat48> moreExternalState;
void doSomethingComplicatedAndFlaky() {
    FlakyLibrary::mat4& m = FlakyLibrary::Oracle::Query();
    MyMat48 newItem;
    init(newItem, m);
    moreExternalState.push_back(newItem);
}

所以这应该可以工作,我可以在幸福的无知中使用MyMat48,并且无需将Flaky链接到我使用FDS.h的其他任何编译单元。它实现了以不依赖于感知其类型定义的方式定义此Mat48结构的目标,并且利用了所述依赖项提供的功能。

但是,如果我能够减少构建的痛苦,那将是 Really Nice™。尤其是体操只涉及分配价值的感觉。

如果我能以某种方式将init实现为MyMat48的“私人”,则代码会更具表现力。特别是最后一个函数体中的4行确实执行了我想要挤入一行的任务。

我想我在这里错过了一些银弹。我真的希望可以在这里使用右值引用。不知何故。也许它不会减少冗长,但也许它可以让它更清楚发生了什么?我还质疑临时对象究竟发生了什么,以及如何确保移动而不是复制的东西(应该是)。

也许我可以设计init更好......

0 个答案:

没有答案