accessing protected members of superclass in C++ with templates
This can be amended by pulling the names into the current scope using using
:
template<typename T> struct Subclass : public Superclass<T> {
using Superclass<T>::b;
using Superclass<T>::g;
void f() {
g();
b = 3;
}
};
Or by qualifying the name via the this
pointer access:
template<typename T> struct Subclass : public Superclass<T> {
void f() {
this->g();
this->b = 3;
}
};
Or, as you’ve already noticed, by qualifying the full name.
The reason why this is necessary is that C++ doesn’t consider superclass templates for name resolution (because then they are dependent names and dependent names are not considered). It works when you use Superclass<int>
because that’s not a template (it’s an instantiation of a template) and thus its nested names are not dependent names.
Cannot access protected class member on the second level of inheritance of class templates in C++
Your class2
definition is the same as the following:
template <typename T> class class2: public class1<T>
{
private: // default section
using class1<T>::a;
T otherData;
public:
class2();
};
It is because private
is the default section for the members of class
es. So the a
member becomes private here and can't be inherited by the class3
. You should explicitly place using class1<T>::a;
statement in protected
or public
section of the class2
definition:
template <typename T> class class2: public class1<T>
{
T otherData;
protected: // <-- added
using class1<T>::a;
public:
class2();
};
Now it can be accessed from the class2
derived classes (including class3
).
Accessing protected members in a derived class
A class can only access protected members of instances of this class or a derived class. It cannot access protected members of instances of a parent class or cousin class.
In your case, the Derived
class can only access the b
protected member of Derived
instances, not that of Base
instances.
Changing the constructor to take a Derived
instance will solve the problem.
Protected member is not declared in this scope in derived class
To fix this, you need to specify Base<T>::data_.clear()
or this->data_.clear()
. As for why this happens, see here.
Access protected members of base class in grandchild class
Your problem is that you're inheriting from you base classes privately, so public and protected members of the base class get the same access control as private members of the derived class. While possible, private inheritance is a very specific tool and used rarely. In the vast majority of cases, you want public inheritance:
class SmallBox: public Box {
protected:
double height;
};
class TooSmall: public SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};
Done this way, protected members will be visible to all descendants (not just direct children) normally.
If, for some reason, you want to stick with private inheritance, you will have to "promote" the privately-inherited protected members back to protected:
class SmallBox:Box {
protected:
double height;
using Box::width; // make it protected again
};
class TooSmall:SmallBox {
public:
void setSmallWidth( double wid );
void setHeight(double hei);
double getSmallWidth( void );
double getHeight(void);
};
Accessing protected static members of Superclass by Sub-classes in C++
Define that static
member out of the class declaration:
class Commands {
protected:
static Container database; // <-- It's just a declration
};
Container Commands::database; // <-- You should make a definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The declaration of a static data member in its class definition is not
a definition ... The definition for a static data member shall appear
in a namespace scope enclosing the member’s class definition.
Your way to make it protected
is OK to make it accessible for derived classes.
Calling protected ctor of inheriting class from within static template method of base class fails
Since your create()
function won't be able to deal with further inherited classes you can take advantage of this and not create a Button
but, instead, a generic derived, protected, derived class which would have access to your protected
constructor:
class Component {
uint32_t id;
template <typename T>
struct Concrete: T {
Concrete(uint32_t id): T(id) {}
};
protected:
Component(uint32_t id) :
id(id) {
}
template<typename T, uint32_t C>
static T* createComponent() {
// content here not relevant
return new Concrete<T>(C);
}
};
class Button:
public Component {
protected:
Button(uint32_t id): Component(id) {}
public:
static Button* create() {
return createComponent<Button, UI_COMPONENT_BUTTON>();
}
};
Access protected members from templated (static) member function
In the first case bar
is virtual function and foo
accesses it through a pointer to A
thus invoking the function pointer and the specified index of Vtable as layout'ed by class A
. Thus it works.
However, in second case, A::foo
explicitly calls the non-virtual function from different class it has no access to. B::bar
is not a virtual overload of A::bar
- it is completely different unrelated function.
Therefore, making friend class A;
is the neatest you can get, I am afraid.
Related Topics
Link Errors Using <Filesystem> Members in C++17
How to Copy the Contents of an Array to a Std::Vector in C++ Without Looping
Why How to Use 'Std::Move' on a 'Const' Object
Using Bitwise Operators for Booleans in C++
Why Does the Standard Differentiate Between Direct-List-Initialization and Copy-List-Initialization
What Is Wrong with Using Inline Functions
The Intersection of Two Sorted Arrays
Fatal Error: "No Target Architecture" in Visual Studio
Using Vector<Char> as a Buffer Without Initializing It on Resize()
Why Does A%B Produce Sigfpe When B Is Zero
C++ Inherit from Multiple Base Classes with the Same Virtual Function Name
#Include Errors Detected in VScode
How to Create a Simple Qt Console Application in C++
Opencv Cv::Mat and Eigen::Matrix
What Is Return Type of Assignment Operator