Accessing Protected Members of Superclass in C++ with Templates

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 classes. 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



Leave a reply



Submit