So in the header file of my derived class OrderedList I am inheriting some of the functionality of my previously created List class by telling the compiler to use a base class method by using List<DataType>::examplefunction;. All the functions which are not being overrided and that are being declared in the aforementioned way are private members of OrderedList.
So when I run my program, I obtain the error in Microsoft Visual Studio of:
error C2248: 'OrderedList::examplefunction' : cannot access private member declared in class 'OrderedList'
examplefunction is public in the base class List.
Here is a concrete example of what I am working with:
In OrderedList.h,
private:
using List<DataType>::remove;
In List.h,
public:
void remove () throw ( logic_error );
And where remove is in List.cpp as,
void List<DataType>::remove () throw ( logic_error )
{ // Do some operations//
}
Also the declaration in my OrderedList header file is like this:
#include "List.cpp"
template < typename DataType, typename KeyType >
class OrderedList : public List<DataType>
If anyone could enlighten me to what is causing the issue that would be much appreciated.
If exampleFunction is private in your List class, your OrderedList class will not be able to access it. Make it protected instead. See Private and Protected Members : C++
Moving the inherited methods to public and the data members to protected in the OrderedList header file worked.
Update
So this was about a year ago. However, it seems so blatantly obvious now. The instructions that were given said to declare the inherited methods from the base class (List) as private, but in main which was provided by the author of the textbook (for testing purposes) some of the inherited methods were being called. Which while being private were not able to be called by the instance of OrderedList that was being created in main.
The instructions were later corrected by our instructor, but sometimes as a student you can follow along to closely.
Related
If I have a subclass which should only be instantiated by its parent class, is friend the appropriate method for accessing the constructor of the private or protected class?
To clarify, there are already questions where this is proposed as the answer. My question is specifically regarding whether this is the only answer and, if not, whether it is the most appropriate for this situation.
Example:
class Class_A {
public:
class Class_B {
// Adding 'friend' keyword here
friend class Class_A;
int _value;
Class_B(
int value)
:
_value(value)
{
}
};
protected:
static Class_A::Class_B createB(
int value)
{
return Class_B(value);
}
};
Credit goes to #Angew for correcting the first version of this answer. Here comes the update:
You are actually using the wrong term: Class_B is not a subclass of Class_B. The correct term is : nested class. The relationship implied by declaring one class inside another is the following one:
The nested class is a member of the enclosing one, and thus has the same access rights as a member (the nested class is basically an implicit friend of the enclosing class).
I.e. the nested class has access to protected and private members of the enclosing class, but not the other way around. Thus if you want to call a private or protected method (e.g. constructor) making them friends is the way to go.
I have a library given to me where I am supposed to subclass one of its struct for use in my own app. When I do this, it works fine. However, when I change my subclass definition to class instead of struct (and I make sure to public: before everything inside), the compiler (Visual Studio compiler 10) gives me this odd error:
typecast: conversion exists but is inaccessible
The line on which this error occurs looks like this:
LibraryNameSpace::Client c(config_options, &mySublassObject);
I don't understand why a simple change from struct to class creates this error; any compiler-added default constructors would apply to either struct or class, including conversion constructors (if that's the issue here).
Is it perhaps because creating a class subclass from a struct base class is not a good idea?
Members of a 'struct' are public by default, whereas members of a 'class' are private by default. If you do not specify public/private, all members in the 'struct' become private when you change it to 'class'.
Also did you inherit by private or public?
class Subclass : public SuperClass {
public:
// ...
};
I have a template base class.Lets say.
template<class KeyF>
class Base
{
private:
int member1;
char member2;
....
};
I derived another class from above class.
template<class KeyF>
class Derived : public Base<KeyF>
{
public:
void func1() {
<accessing member1/member2>
}
....
};
Above code doesn't compile in gcc. saying that member1 is not a member of Derived. But it is already derived from a Base Class, then why can't it access its member?
Members in Base are private. You cannot access private members of class, outside of this class (except friend). Make them protected, or make protected getters.
You need to prefix base member names with this-> or Base<KeyF>::, or add a using declaration to the class to unhide them. Their names are dependent names, and they are hidden.
Did you try protected? Been a bit since I was deep into C++...
I think two changes needed to solve the issue:
In base class, define the member as "protected" instead of "private" to be accessible in the derived class.
In derived class, add the base class name ahead of the protected member. In this case, it should look like "Base<typename>::member1".
Using C++17 standard in my case, the issue was resolved. Hope this is helpful. Thanks to Kerrek SB for the info.
Sorry if the question is silly. I come from java background.
In the following code, base_list is a parent class of SqlAloc, but what's the meaning of public memory?
class base_list :public memory::SqlAlloc
{
protected:
list_node *first,**last;
uint32_t elements;
public:
};
Memory is probably a namespace (kind of like an outer class) in which SqlAlloc is defined.
C++ has both public and private inheritance (protected, too, actually.) public inheritance is just like Java inheritance; in private inheritance, though, code outside the derived class doesn't know about the base class. It's a way to inherit implementation without inheriting type. In Java, you can only do both.
memory is either a namespace or a class (struct). public means that all member functions and member data which were declared in SqlAlloc class(struct) as public and protected will be visible in base_list as public and protected.
base_list is publicly deriving from SqlAlloc which is either a namespace-class, or nested-class, depending upon what memory is - which could be either a namespace or a class.
Given that we have overloaded methods in base class, and a derived class that was inherited as private/protected.
Can we restore only one/several of the original access level of the overloaded methods?
On GCC 4.4.0 i try to put the base methods under protected access, then inherited it using private access. When i try to restore the access level to public, it works! Is this how its suppose to work? or is it a bug on the compiler? To my understanding, restoring access level shouldn't be able to be used to promote or demote a member's access level.
Code snippet :
class base {
public:
void method() {}
void method(int x) {}
protected:
void method2() {}
};
class derived : private base {
public:
base::method; // Here, i want to restore only the none parameterized method
base::method2; // method2 is now public??
};
Changing accessibility of inherited functions through a using declaration cannot be done selectively on given overload for the simple reason that a using declaration only introduces a name into the declarative region and that by definition, functions overloads share the same name.
The only alternative I see here is to use trivial forwarding functions :
class derived : private base
{
public:
void method() { base::method(); }
using base::method2; // method2 is now public
// method(int) stays inaccessible
};
I'm not quite sure I understand your second question, but yes : you can change base members accessibility in a derived class through using declarations.
You don't restore access, per se. You set access. As you are doing above, you can explicitly set the access for any method, including ones previously declared as private.
It would be impossible to prevent protected methods from being public if the derived class wanted it so, as you could just write a minor wrapper and done. private is another matter.