c++ - Can't access protected member variables of the most base class through std::unique_ptr in diamond -
i not advanced programmer. suppose there classic diamond inheritance:
class base class a: virtual public base class b: virtual public base class last: public a, public b
suppose base
has variable, m_x
, common both a
, b
, such 1 of a
, or b
, can called @ time, not both (which needed). around this, used:
class last: public a, public b { private: std::unique_ptr<base> m_p; public: last(int i) { if (i) m_p = std::unique_ptr<base>(new a()); else m_p = std::unique_ptr<base>(new b()); } };
this fine, m_p->m_x
cannot accessed anymore because says it's protected, both a
, b
call m_x
in constructors directly, no problems.
is known limitation or wrong way it? if it's wrong, solutions there?
here code based on diagram found here (a bit lower on page):
#include <iostream> #include <memory> class power { protected: double m_x; public: power() {} power(double x): m_x {x} {} virtual ~power() = default; }; class scanner: virtual public power { public: scanner() {} scanner(double x): power(x) {} // scan document }; class printer: virtual public power { public: printer() {} printer(double x): power(x) {} // print document }; class copier: public scanner, public printer { private: std::unique_ptr<power> m_p; public: copier() {} copier(double x, int i) { if (i) m_p = std::unique_ptr<power>(new scanner(x)); else m_p = std::unique_ptr<power>(new printer(x)); } void print() { std::cout << this->power::m_x << '\n'; } }; int main(int argc, char *argv[]) { copier *copier {new copier(1.618, 0)}; copier->print(); copier = new copier(3.14, 1); copier->print(); return 0; }
using both this->m_p
, this->power::m_x
(according answers , comments) compiles, output 0
.
to sure spell out all: not quite beginner, but, given example above, oesn't have stay way if there alternative call scanner
or printer
1 @ time inside copier
. not asking opinions, understand it's forbidden, won't reject them coming more experienced users. after all, learning.
both virtual inheritance , std::unique_ptr
red herrings. problem comes down this:
class base { protected: int m_x; }; class last : public base { public: last() { base base; base.m_x = 0; // error m_x = 1; // no error } };
the error error c2248: 'base::m_x': cannot access protected member declared in class 'base'
or error: 'int base::m_x' protected within context
.
the explanation protected
special case. not work on class level also on object level. , have 2 relevant objects here:
- the
last
object being created constructor, i.e. 1 pointedthis
. it'sbase
object because of is-a inheritance relationship. - the local object named
base
within constructor.
now, problem in line base.m_x = 0;
, in context of first object , not second one. in other words, trying access m_x
of base
outside base
. c++ not allow this.
a technical explanation can found in c++ standard @ §11.4 [class.protected]
, more understandable 1 in excellent answer here on stack overflow.
Comments
Post a Comment