Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>So basically, I need a design that allows someClass to be a virtual interface</p> </blockquote> <p>If I understand you correctly, this intention contradicts the solution you have came up with. The virtual inheritance concerns only virtual member functions. And there is no way you could dynamically inherit nested structs because it is a subject of the lexical meta-programming which is not supported in C++.</p> <p>My suggestion is to think carefully if you can make your object immutable. Then some adaptation of the Builder/Factory design pattern will allow you to eliminate the usage of properties.</p> <p>You may also consider to write a code generator. In case if you pick up a good markup keywords, it may be easy.</p> <p><strong>UPDATE</strong> I've added some code to clarify my suggestion. </p> <p>First of all we prepare some auxiliary objects. They should be put in a header file accessible for both the Library and the Client. These objects will never be modified.</p> <p>GetSetProp &lt;>----> IGetSetProp &lt;----- PropFunctionAdapter</p> <pre><code>template&lt;class _Ty&gt; struct __declspec(novtable) IGetSetProp { typedef std::tr1::shared_ptr&lt;IGetSetProp&lt;_Ty&gt;&gt; ptr_t; virtual void set_Prop(_Ty const&amp; val); virtual _Ty get_Prop() const; }; template&lt;typename _Ty&gt; class PropFunctionAdapter : public IGetSetProp&lt;_Ty&gt; { std::function&lt;_Ty(void)&gt; getter; std::function&lt;void(_Ty const&amp;)&gt; setter; public: PropFunctionAdapter(std::function&lt;_Ty(void)&gt; _getter, std::function&lt;void(_Ty const&amp;)&gt; _setter) : getter(_getter) , setter(_setter) { // One may want to verify that getter and setter are not empty } virtual ~PropFunctionAdapter() throw() {} inline static std::tr1::shared_ptr&lt;typename PropFunctionAdapter&lt;_Ty&gt;&gt; Create(std::function&lt;_Ty(void)&gt; _getter, std::function&lt;void(_Ty const&amp;)&gt; _setter) { return std::make_shared&lt;typename PropFunctionAdapter&lt;_Ty&gt;&gt;(_getter, _setter); } public: void set_Prop(_Ty const&amp; val) { setter(val); } _Ty get_Prop() const { return getter(); } }; template&lt;class _Owner, class _Ty&gt; typename IGetSetProp&lt;_Ty&gt;::ptr_t CreateAdapter(_Owner&amp; source, _Ty(_Owner::*getter)() const, void(_Owner::*setter)(_Ty const&amp;)) { return PropFunctionAdapter&lt;_Ty&gt;::Create( std::tr1::bind(std::mem_fn(getter), &amp;source), std::tr1::bind(std::mem_fn(setter), &amp;source, std::tr1::placeholders::_1)); } template&lt;class _Ty&gt; class GetSetProp { typename IGetSetProp&lt;_Ty&gt;::ptr_t prop; public: GetSetProp(typename IGetSetProp&lt;_Ty&gt;::ptr_t _prop) : prop(_prop) { } GetSetProp&lt;_Ty&gt;&amp; operator= (_Ty const&amp; val) { prop-&gt;set_Prop(val); return *this; } operator _Ty() const { return prop-&gt;get_Prop(); } }; </code></pre> <p>Similarly you may define GetProperty and SetProperty.</p> <p>Suppose you have a data contract containing two fields Pressure:int and Description:string. Then you define the data contract:</p> <pre><code>class BaseClass { public: GetSetProp&lt;int&gt; Pressure; GetSetProp&lt;std::string&gt; Description; protected: BaseClass(IGetSetProp&lt;int&gt;::ptr_t fieldA, IGetSetProp&lt;std::string&gt;::ptr_t fieldB) : Pressure(fieldA) , Description(fieldB) { } virtual ~BaseClass() throw() {} }; </code></pre> <p>And its implementation in the library:</p> <pre><code>class DerivedClass : public BaseClass { public: // Here you initialize fields assigning them correspondent setters and getters // You may define an ATL-like mapping in order to hide implementation details DerivedClass() : BaseClass( CreateAdapter(*this, &amp;DerivedClass::get_Pressure, &amp;DerivedClass::set_Pressure) , CreateAdapter(*this, &amp;DerivedClass::get_Description, &amp;DerivedClass::set_Description)) { } virtual ~DerivedClass() throw() {} private: void set_Pressure(int const&amp; value) { val = value; } int get_Pressure() const { return val; } void set_Description(std::string const&amp; description) { this-&gt;description = description; } std::string get_Description() const { return description; } private: int val; std::string description; }; // The client-side code DerivedClass d; BaseClass&amp; b = d; b.Description = "Hello"; std::string descr = b.Description; b.Pressure = 2; int value = b.Pressure; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload