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:

  1. the last object being created constructor, i.e. 1 pointed this. it's base object because of is-a inheritance relationship.
  2. 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

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -