Visibility issue for base class copy constructor

I have a class (let it be called base at the moment) that has a secure interface, including protected constructors, etc. Some base functions return an instance of base by value:

 class base { protected: base() {} base (base const &other) {} // line 6 base foo () { base ret; return ret; } }; 

These functions are wrapped in derived classes to return a derived type as follows:

 class derived : public base { private: derived(base const &b) : base(b) {} public: derived() : base() {} derived foo() { derived d(base::foo()); // line 21 return d; } }; 

To facilitate the conversion from the base return type to the returned type, I provide a private constructor in derived that handles this.

Compiling on Centos 5.8 with gcc 4.1.2 causes the following error:

 test.cpp: In member function 'derived derived::foo()': test.cpp:6: error: 'base::base(const base&)' is protected test.cpp:21: error: within this context 

With gcc 4.6.1 and clang 2.9 on Linux Mint 12, the code compilation file, even with -Wall -Wextra , besides the unused parameter warning for the base copy constructor.

I think this may be a compiler error in gcc 4.1.2, but I could not find anything on the net. Has anyone seen this before?

I canโ€™t update the compiler without much pain. Is there a simple workaround besides creating a constructor for copying a base class?


EDIT I added base b; to line 21 in derived::foo() . In this case, gcc 4.6.1 and gcc 4.1.2 report that by default ctor base is protected, clang 2.9 compiles without warning. This is what David Rodriguez - drieba said in his comment - by default, ctor cannot be called on another instance of base .


EDIT 2 The standard paragraph that appears to apply here is 11.5 [class.protected]. gcc 4.1.2 seems to correctly reject my code as incorrect, and I wonder why gcc 4.6.1 and clang allow this. See My own answer for a preliminary solution.

+6
source share
2 answers

My preliminary decision is to make base copy ctor public . To prohibit copying derived instances using the ctor base copy, inheritance should be protected instead of public . The resulting classes now look like this:

 class base { protected: base() {} public: base (base const &other) {} protected: base foo () { base ret; return ret; } }; class derived : protected base { private: derived(base const &b) : base(b) {} public: derived() : base() {} derived foo() { derived d(base::foo()); return d; } }; 
0
source

A workaround to which you could try would be to create a private constructor for the derivative, which creates its base by calling the base function:

 class derived : base { struct from_base_foo {}; derived( from_base_foo ) : base( base::foo() ) {} public; derived foo() { return derived( from_base_foo() ); } }; 
+1
source

Source: https://habr.com/ru/post/920427/


All Articles