1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
#include <iostream>
#include <string>
struct Thing {
struct PartialData { std::string codeName; int width, length, height, mass; }; // ***Added
struct PartialDataTag {}; // ***Added
std::string name, codeName;
int width, length, height, mass;
Thing() = default;
Thing (const std::string& n) : name(n) {}
Thing (const std::string& n, int l, int h) : name(n), length(l), height(h) {}
Thing (const std::string& n, const std::string& c, int w, int l, int h, int m) :
name(n), codeName(c), width(w), length(l), height(h), mass(m) {}
Thing (const std::string& n, const PartialData& data) :
name(n), codeName(data.codeName), width(data.width), length(data.length), height(data.height), mass(data.mass) {}
void print() const {std::cout << name << ", " << codeName << ", " << width << ", " << length << ", " << height << ", " << mass << '\n';}
protected:
void setUsingPartialData (const PartialData& data) {
codeName = data.codeName; width = data.width; length = data.length; height = data.height; mass = data.mass;
}
virtual void foo() = 0;
};
struct Clone : virtual Thing {
Thing& parent;
template <typename... Args>
Clone (Thing& p, Args&&... args) : Thing (std::forward<Args>(args)...), parent(p) {}
};
template <typename T>
struct ClonedType : public Clone, public T {
template <typename... Args>
ClonedType (Thing& t, Args&&... args) : Thing (std::forward<Args>(args)...), Clone(t, std::forward<Args>(args)...), T(PartialDataTag{}) {}
};
struct Blob : virtual Thing {
static const PartialData partialData;
Blob (const std::string& name) : Thing (name, partialData) {}
Blob (PartialDataTag) {setUsingPartialData(partialData);}
virtual void foo() override {}
};
const Thing::PartialData Blob::partialData = {"Bob", 3, 4, 5, 20}; // !
struct Sample : virtual Thing {
static const int staticWidth = 10, staticMass = 50;
Sample (const std::string& name, int length, int height) : Thing(name, "Sam", staticWidth, length, height, staticMass) {}
Sample (PartialDataTag) {setUsingPartialData(getPartialData());}
virtual void foo() override {}
PartialData getPartialData() const {return {"Sam", staticWidth, length, height, staticMass};} // !
};
int main() {
Blob blob("Blob");
ClonedType<Blob> b(blob, "New Blob");
blob.print(); // Blob, Bob, 3, 4, 5, 20
b.print(); // New Blob, Bob, 3, 4, 5, 20
Sample sample("Sample", 11, 12);
ClonedType<Sample> s(sample, "New Sample", 21, 22);
sample.print(); // Sample, Sam, 10, 11, 12, 50
s.print(); // Sample, Sam, 10, 21, 22, 50
}
|